printf("Processus %d avec pere %d, i = %d\n",getpid(),getppid(),i);
}
returnEXIT_SUCCESS;
}
```
Dont voici une exécution
```sh
bash-4.4$ ./fork2
Processus 20276 avec pere 20274, i=1
Processus 20275 avec pere 20274, i=0
Processus 20278 avec pere 20275, i=1
Processus 20277 avec pere 20274, i=2
Processus 20279 avec pere 20276, i=2
Processus 20280 avec pere 20274, i=3
Processus 20281 avec pere 20275, i=2
Processus 20282 avec pere 20278, i=2
Processus 20283 avec pere 20277, i=3
Processus 20284 avec pere 20276, i=3
Processus 20286 avec pere 20279, i=3
Processus 20287 avec pere 1, i=4
Processus 20285 avec pere 1, i=4
Processus 20288 avec pere 20275, i=3
bash-4.4$ Processus 20290 avec pere 20278, i=3
Processus 20289 avec pere 20281, i=3
Processus 20292 avec pere 1, i=4
Processus 20291 avec pere 1, i=4
Processus 20294 avec pere 1, i=4
Processus 20293 avec pere 20282, i=3
Processus 20295 avec pere 1, i=4
Processus 20296 avec pere 1, i=4
Processus 20298 avec pere 1, i=4
Processus 20299 avec pere 1, i=4
Processus 20300 avec pere 1, i=4
Processus 20297 avec pere 1, i=4
Processus 20302 avec pere 1, i=4
Processus 20301 avec pere 1, i=4
Processus 20304 avec pere 1, i=4
Processus 20303 avec pere 1, i=4
Processus 20305 avec pere 1, i=4
```
## Les appels système wait(), waitpid() et exit()
Ces appels système permettent au processus père d’attendre la fin d’un de ses processus fils et de récupérer son status de fin. Ainsi, un processus peut synchroniser son exécution avec la fin de son processus fils en exécu- tant l’appel système wait():
```c
intwait(int*status);
```
> permet à un processus père d'attendre jusqu'à ce que le procesuss fils termine. La fonction retourne l'identifiant du processus fils à l'adresse de status
```c
intwaitpid(intpid,int*status,intoptions);
```
> permet à un processus père d'attendre jusqu'à ce que le processus fils de numéro pid termine, il retourne l'identifiant du processus fils et son état de terminaison à l'adresse de status.
Si le processus appelant ```wait()``` n'a pas de fils alors la fonction renvoie une erreur.
#### Exemple 1
```c
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main() {
pid_t fils_pid ;
fils_pid = fork ();
if ( fils_pid == 0) {
printf("Je suis le fils avec pid %d\n",getpid()); exit(3);
} else {
if (fils_pid > 0) {
printf ("Je suis le pere avec pid %d.\n" , getpid ());
printf("J’attends que mon fils se termine\n");
wait (NULL) ;
printf("Normalement mon fils en a fini!\n");
} else {
printf("Erreur dans la creation du fils\n");
}
}
exit (0);
}
```
Dont une exécution est
```sh
bash-4.4$ ./wait
Je suis le pere avec pid 20892.
J’attends que mon fils se termine
Je suis le fils avec pid 20893
bash-4.4$
```
#### Exemple 2
```c
/* fork2b.c */
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int i, n = 5;
pid_t childpid;
for (i=0; i<n; i++) {
if ((childpid = fork()) == -1) break;
if (childpid == 0)
printf("Processus %d avec pere %d, i = %d\n", getpid(), getppid(), i);
}
while (wait(NULL) >= 0)
;
return EXIT_SUCCESS;
}
```
Avec une exécution possible :
```sh
bash-4.4$ ./fork2b
Processus 21041 avec pere 21039, i = 1
Processus 21040 avec pere 21039, i = 0
Processus 21042 avec pere 21039, i = 2
Processus 21044 avec pere 21040, i = 1
Processus 21043 avec pere 21039, i = 3
Processus 21045 avec pere 21042, i = 3
Processus 21046 avec pere 21041, i = 2
Processus 21047 avec pere 21039, i = 4
Processus 21048 avec pere 21040, i = 2
Processus 21049 avec pere 21044, i = 2
Processus 21050 avec pere 21042, i = 4
Processus 21051 avec pere 21043, i = 4
Processus 21052 avec pere 21045, i = 4
Processus 21053 avec pere 21041, i = 3
Processus 21054 avec pere 21046, i = 3
Processus 21055 avec pere 21040, i = 3
Processus 21056 avec pere 21048, i = 3
Processus 21057 avec pere 21044, i = 3
Processus 21058 avec pere 21049, i = 3
Processus 21059 avec pere 21041, i = 4
Processus 21061 avec pere 21040, i = 4
Processus 21060 avec pere 21046, i = 4
Processus 21063 avec pere 21053, i = 4
Processus 21062 avec pere 21048, i = 4
Processus 21065 avec pere 21044, i = 4
Processus 21064 avec pere 21054, i = 4
Processus 21066 avec pere 21049, i = 4
Processus 21067 avec pere 21055, i = 4
Processus 21069 avec pere 21057, i = 4
Processus 21070 avec pere 21058, i = 4
Processus 21068 avec pere 21056, i = 4
bash-4.4$
```
##### Questions
1- Quelle est la valeur de retour de ```wait``` si il n'y a pas de fils
2- Dessiner le graphe quand ```n = 3```, pour ```fork2b.c```.
3- Ecrire un programme qui nous permet de savoir si ```wait()``` attend un ou tous les procesuss
### Exemple 3
```c
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void fils(int i);
int main() {
int status ;
pid_t pid;
pid = fork();
if (pid == -1) perror("fork");
else if (pid ==0) // creation du second fils
fils (1) ;
pid = fork();
if (pid == -1) perror("fork");
else if (pid ==0) // creation du second fils
fils (2) ;
if (wait(&status) > 0)
printf("fin du fils %d\n", WEXITSTATUS(status));
else perror("wait");
if (wait(&status) > 0)
printf("fin du fils %d\n", WEXITSTATUS(status));
else perror("wait");
if (wait(&status) > 0)
printf("fin du fils %d\n", WEXITSTATUS(status));
else perror("wait");
return 0 ;
}
void fils (int i) {
sleep(2);
exit(i);
}
```
##### Questions
1- Analyser le code précédent
2- Depuis le shell on peut envoyer un signal à un processus via ```kill```. Faire un programme C qui affiche le signal qui a été envoyé à un processus créé.
### Processus zombie
L’exécution asynchrone entre processus parent et fils a certaines conséquences. Souvent, le fils d’un processus se termine, mais son père ne l’attend pas. Le processus fils devient alors un processus zombie. Le processus fils existe toujours dans la table des proces- sus, mais il n’utilise plus les ressources du *kernel*.
L’exécution de l’appel système ```wait()``` ou ```waitpid()``` par le processus père élimine le fils de la table des processus. Il peut y avoir aussi des terminaisons prématurées, où le processus parent se termine avant ses processus fils. Dans cette situation, ses processus fils sont adoptés par le processus ```init```, dont le ```pid = 1```.
printf("Je suis le fils avec pid %d\n",getpid());sleep(1);exit(3);
}else{
if(fils_pid>0){
printf("Je suis le pere avec pid %d.\n",getpid());
printf("J’attends que mon fils se termine\n");
wait(NULL);
printf("Normalement mon fils en a fini!\n");
}else{
printf("Erreur dans la creation du fils\n");
}
}
exit(0);
}
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.