# TD2 : Unix ###### tags: `unix` `2022` ## Exercice 2.2 ### 1. ```c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(int argc, char *argv[]) { int n = 3; int i = 0; pid_t pid; fprintf(stdout, "Avant le fork\n"); // création des 3 fils while(i < n) { fprintf(stdout, "i=%d\n", i); if((pid = fork()) == 0) { fprintf(stdout, "Je suis un processus fils... : %d\n", getpid()); break; } else { waitpid(pid, 0, 0); i++; } } return 0; } ``` ![](https://i.imgur.com/NxPXuIt.png) ### 2. Écrire un programme C qui crée un nombre aléatoire de processus, chaque processus fils devra attendre un temps aléatoire compris entre 1 et 100 secondes (fonction sleep(int nb_sec)) avant de se terminer. ```c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <time.h> #include <stdlib.h> int main(int argc, char *argv[]) { srand(time(NULL)); int n = (rand() % 20) + 1; int i = 0; pid_t pid; // création des n processus while(i < n) { if((pid = fork()) == 0) { break; } else { i++; } } if(pid == 0) { srand(time(NULL) ^ (getpid()<<16)); int slp_tm = (rand() % 100) + 1; // sleep avec un temps aléatoire sleep(slp_tm); printf("fils : je suis mort après %d secondes.\n", slp_tm); } else { printf("père : je suis mort.\n"); } return 0; } ``` ![](https://i.imgur.com/usiLFZI.png) ### 3. Faire évoluer le programme de façon à ce qu’à chaque mort, le processus père devra afficher le PID du défunt fils, jusqu’à ce que tous ses fils soient morts. ```c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <time.h> #include <stdlib.h> int main(int argc, char *argv[]) { int n = (rand() % 20) + 1; int i = 0; pid_t pid; while(i < n) { if((pid = fork()) == 0) { break; } else { i++; } } if(pid == 0) { srand(time(NULL) ^ (getpid()<<16)); int slp_tm = (rand() % 100) + 1; sleep(slp_tm); } else { while(1) { pid = waitpid(-1, 0, WNOHANG | WCONTINUED); if(pid == -1) break; // erreur (pas de fils à attendre) if(pid != 0) { // fils est mort printf("père : Le fils au pid = %d est mort.\n", pid); } else { } // rien ne s'est passé } printf("père : je suis mort.\n"); } return 0; } ``` ### 4. Reprendre le programme précédant en modifiant la phase d’attente de la mort des fils : le père devra afficher un point ou une étoile toutes les secondes : — un point si aucun fils n’est mort depuis le précédent affichage, — ou une étoile si au moins un fils est mort depuis le précédent affichage ```c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <time.h> #include <stdlib.h> int main(int argc, char *argv[]) { int n = (rand() % 100) + 1; int i = 0; pid_t pid; while(i < n) { if((pid = fork()) == 0) { break; } else { i++; } } if(pid == 0) { srand(time(NULL) ^ (getpid()<<16)); int slp_tm = (rand() % 100) + 1; sleep(slp_tm); } else { while(1) { pid = waitpid(-1, 0, WNOHANG | WCONTINUED); if(pid == -1) break; // erreur (pas de fils à attendre) if(pid != 0) { // fils est mort printf(".\n"); } else { // rien ne s'est passé printf("*\n"); } sleep(1); } printf("père : je suis mort.\n"); } return 0; } ``` ![](https://i.imgur.com/ITX3fHj.png) ## Exercice 2.3 ```c #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <time.h> #include <stdlib.h> int main(int argc, char *argv[]) { pid_t pid_fils; int fd_tube[2]; pipe(fd_tube); pid_fils = fork(); if(pid_fils == 0) { close(fd_tube[0]); printf("Fils: Je dors 5 secondes avant d'envoyer un message à papa...\n"); sleep(5); char msg[64] = "Salut papa ça va ?"; write(fd_tube[1], msg, 64); printf("Fils: C'est fait papa.\n"); } else { close(fd_tube[1]); printf("Le père va lire un message dans le tube...\n"); char *msg; read(fd_tube[0], msg, 64); printf("Le message est %s\n", msg); } return 0; } ```