table of contents
WAIT(2) | Manuel du programmeur Linux | WAIT(2) |
NOM¶
wait, waitpid, waitid - Attendre la fin d'un processusSYNOPSIS¶
#include <sys/types.h>Exigences de macros de test de fonctionnalités pour la glibc (consultez feature_test_macros(7)) :
_SVID_SOURCE ||
_XOPEN_SOURCE >= 500 ||
_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Depuis la glibc 2.12 : */
_POSIX_C_SOURCE >= 200809L
DESCRIPTION¶
Tous ces appels système attendent qu'un des fils du processus appelant change d'état, et permettent d'obtenir des informations sur le fils en question. Un processus est considéré comme changeant d'état s'il termine, s'il est stoppé par un signal, ou s'il est relancé par un signal. Dans le cas d'un fils qui se termine, l'attendre permet au système de libérer les ressources qui lui étaient allouées ; si le processus n'est pas attendu, il reste en état de « zombie » (voir les NOTES plus bas).wait() et waitpid()¶
L'appel système wait() suspend l'exécution du processus appelant jusqu'à ce que l'un de ses enfants se termine. L'appel wait(&status) est équivalent à :waitpid(-1, &status, 0);
- < -1
- Attendre la fin de n'importe quel processus fils appartenant au groupe de processus d'ID -pid.
- -1
- Attendre n'importe lequel des processus fils.
- 0
- Attendre la fin de n'importe quel processus fils du même groupe que l'appelant.
- > 0
- Attendre la fin du processus numéro pid.
- WNOHANG
- Ne pas bloquer si aucun fils ne s'est terminé.
- WUNTRACED
- Recevoir l'information concernant également les fils bloqués (mais non suivis par ptrace(2)) si on ne l'a pas encore reçue. L'état des fils suivis est fourni même sans cette option.
- WCONTINUED (Depuis Linux 2.6.10)
- Renvoyer également si un processus fils stoppé a été relancé par le signal SIGCONT.
- WIFEXITED(status)
- Vrai si le fils s'est terminé normalement, c'est-à-dire par un appel à exit(3) ou _exit(2), ou par un return depuis main().
- WEXITSTATUS(status)
- Donne le code de retour, consistant en les 8 bits de poids faibles du paramètre status fourni à exit(3) ou _exit(2) ou dans le return de la routine main(). Cette macro ne peut être évaluée que si WIFEXITED est non nul.
- WIFSIGNALED(status)
- Vrai si le fils s'est terminé à cause d'un signal non intercepté.
- WTERMSIG(status)
- Donne le numéro du signal qui a causé la fin du fils. Cette macro ne peut être évaluée que si WIFSIGNALED est non nul.
- WCOREDUMP(status)
- Vrai si le processus fils a produit une image mémoire (« core dump »). Cette macro ne doit être évaluée que si WIFSIGNALED a renvoyé une valeur non nulle. Cette macro n'est pas décrite par POSIX.1-2001 et n'est pas disponible sur certaines variantes d'UNIX (par exemple AIX ou SunOS). N'utilisez cette macro qu'entourée de #ifdef WCOREDUMP ... #endif.
- WIFSTOPPED(status)
- Vrai si le fils est actuellement arrêté. Cela n'est possible que si l'on a effectué l'appel avec l'option WUNTRACED ou si le fils est suivi (voir ptrace(2)).
- WSTOPSIG(status)
- Donne le numéro du signal qui a causé l'arrêt du fils. Cette macro ne peut être évaluée que si WIFSTOPPED est non nul.
- WIFCONTINUED(status)
- (Depuis Linux 2.6.10) Vrai si le processus fils a été relancé par SIGCONT.
waitid()¶
L'appel système waitid(), disponible depuis Linux 2.6.9, fournit des moyens plus fins de contrôler quels changements d'états attendre.- idtype == P_PID
- Attendre la fin du processus numéro id.
- idtype == P_PGID
- Attendre la fin de n'importe quel processus fils appartenant à un groupe de processus d'ID id.
- idtype == P_ALL
- Attendre n'importe quel fils ; l'argument id est ignoré.
- WEXITED
- Attendre les fils qui se sont terminés.
- WSTOPPED
- Attendre les enfants qui ont été arrêtés par un signal.
- WCONTINUED
- Attendre les enfants précédemment arrêtés qui ont été relancés par le signal SIGCONT.
- WNOHANG
- Comme pour waitpid().
- WNOWAIT
- Laisser le fils dans un état prêt ; un appel ultérieur à wait() pourra de nouveau fournir des informations sur l'état du fils.
- si_pid
- L'identifiant de processus du fils.
- si_uid
- L'UID réel du fils. Ce champ n'est pas rempli par la plupart des autres implémentations.
- si_signo
- Toujours SIGCHLD.
- si_status
- Soit le code de retour du fils donné à _exit(2) ou exit(3), soit le signal ayant provoqué la terminaison, l'arrêt, ou la relance du fils. Le champ si_code permet de savoir comment interpréter ce champ.
- si_code
- L'un de CLD_EXITED (le fils a appelé _exit(2)), CLD_KILLED (le fils a été tué par un signal), CLD_DUMPED (le fils a été tué par un signal, et a produit une image (core dump)), CLD_STOPPED (le fils a été arrêté par un signal), CLD_TRAPPED (le fils suivi a été rattrapé) ou CLD_CONTINUED (le fils a été relancé par SIGCONT).
VALEUR RENVOYÉE¶
wait() : en cas de réussite, l'identifiant du processus fils terminé est renvoyé ; en cas d'erreur, la valeur de retour est -1.ERREURS¶
- ECHILD
- (pour wait()) Le processus appelant n'a pas de fils qui n'ont pas été attendus.
- ECHILD
- (pour waitpid() ou waitid()) Le processus indiqué par pid ( waitpid()) ou idtype et id ( waitid()) n'existe pas, ou n'est pas un fils du processus appelant. (Ceci peut arriver pour son propre fils si l'action de SIGCHLD est placé sur SIG_IGN, voir également le passage de la section Notes sur Linux concernant les threads.)
- EINTR
- WNOHANG n'est pas indiqué, et un signal à intercepter ou SIGCHLD a été reçu ; consultez signal(7).
- EINVAL
- L'argument options est invalide.
CONFORMITɶ
SVr4, BSD 4.3, POSIX.1-2001.NOTES¶
Un fils qui se termine mais n'a pas été attendu devient un « zombie ». Le noyau conserve des informations minimales sur le processus zombie (identifiant, code de retour, informations d'utilisation des ressources) pour permettre au parent de l'attendre plus tard et d'obtenir des informations sur le fils. Tant que le zombie n'est pas effacé du système par une attente, il prendra un emplacement dans la table des processus du noyau, et si cette table est remplie, il sera impossible de créer de nouveaux processus. Si un processus parent se termine, ses fils zombies sont adoptés par init(8), qui les attend automatiquement pour les supprimer.Notes sur Linux¶
Dans le noyau Linux, un thread ordonnancé par le noyau n'est pas différent d'un simple processus. En fait, un thread est juste un processus qui est créé à l'aide de la routine — spécifique à Linux — clone(2). Les routines portables, comme pthread_create(3), sont implémentées en appelant clone(2). Avant Linux 2.4, un thread était simplement un cas particulier de processus, et en conséquence un thread ne pouvait pas attendre les enfants d'un autre thread, même si ce dernier appartenait au même groupe de threads. Toutefois, POSIX réclame une telle fonctionnalité, et depuis Linux 2.4 un thread peut, par défaut, attendre les enfants des autres threads du même groupe. Les options suivantes sont spécifiques à Linux, et servent pour les enfants créés avec clone(2) ; elles ne peuvent pas être utilisées avec waitid() :- __WCLONE
- Attendre uniquement des enfants clones. Sinon, attendre uniquement les enfants non-clones (un enfant « clone » est un enfant qui n'envoie pas de signal, ou un autre signal que SIGCHLD à son père à sa terminaison). Cette option est ignorée si __WALL est aussi indiqué.
- __WALL (depuis Linux 2.4)
- Attendre tous les enfants, quel que soit leur type (clone ou non-clone).
- __WNOTHREAD (Depuis Linux 2.4)
- Ne pas attendre les enfants des autres threads du même groupe de threads. Ceci était le cas par défaut avant Linux 2.4.
EXEMPLE¶
Le programme suivant montre l'utilisation de fork(2) et de waitpid(). Le programme crée un processus fils. Si aucun argument n'est fourni dans la ligne de commande du programme, le fils suspend son exécution avec pause(2), pour que l'utilisateur puisse lui envoyer des signaux. Sinon, le fils se termine immédiatement, en utilisant l'entier fourni sur la ligne de commande comme code de retour. Le processus père boucle en surveillant l'état du fils avec waitpid(), et utilise les macros W*() décrites ci-dessus pour analyser le code d'état du fils.$ ./a.out & Le PID du fils est 32360 [1] 32359 $ kill -STOP 32360 arrêté par le signal 19 $ kill -CONT 32360 relancé $ kill -TERM 32360 tué par le signal 15 [1]+ Done ./a.out $
Source du programme¶
#include <sys/wait.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> int main(int argc, char *argv[]) { pid_t cpid, w; int status; cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { /* Code exécuté par le fils */ printf("Le PID du fils est %ld\n", (long) getpid()); if (argc == 1) pause(); /* Attendre un signal */ _exit(atoi(argv[1])); } else { /* Code exécuté par le père */ do { w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { printf("terminé, code=%d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("tué par le signal %d\n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("arrêté par le signal %d\n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("relancé\n"); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); exit(EXIT_SUCCESS); } }
VOIR AUSSI¶
_exit(2), clone(2), fork(2), kill(2), ptrace(2), sigaction(2), signal(2), wait4(2), pthread_create(3), credentials(7), signal(7)COLOPHON¶
Cette page fait partie de la publication 3.44 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies peuvent être trouvées à l'adresse <http://www.kernel.org/doc/man-pages/>.TRADUCTION¶
Depuis 2010, cette traduction est maintenue à l'aide de l'outil po4a <http://po4a.alioth.debian.org/> par l'équipe de traduction francophone au sein du projet perkamon <http://perkamon.alioth.debian.org/>. Christophe Blaess <http://www.blaess.fr/christophe/> (1996-2003), Alain Portal <http://manpagesfr.free.fr/> (2003-2006). Julien Cristau et l'équipe francophone de traduction de Debian (2006-2009). Veuillez signaler toute erreur de traduction en écrivant à <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le paquet manpages-fr. Vous pouvez toujours avoir accès à la version anglaise de ce document en utilisant la commande « man -L C <section> <page_de_man> ».26 septembre 2010 | Linux |