| wait(2) | System Calls Manual | wait(2) |
NAVN¶
wait, waitpid, waitid - vent på at processen ændrer tilstand
BIBLIOTEK¶
C-standardbibliotek (libc, -lc)
SYNOPSIS¶
#include <sys/wait.h>
pid_t wait(int *_Nullable wstatus); pid_t waitpid(pid_t pid, int *_Nullable wstatus, int tilvalg);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
/* Dette er glibc- og POSIX-grænsefladen; se
VERSIONS for information om det rå systemkald. */
waitid():
Siden glibc 2.26:
_XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200809L
glibc 2.25 og tidligere:
_XOPEN_SOURCE
|| /* Siden glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
|| /* glibc <= 2.19: */ _BSD_SOURCE
BESKRIVELSE¶
Alle disse systemkald bruges til at vente på tilstandsændringer i en underproces af den kaldende proces, og hente information om underprocessen, hvis tilstand har ændret sig. En tilstandsændring anses for at være: underprocessen afsluttedes; underprocessen blev stoppet af et signal; eller underprocessen blev genoptaget af et signal. I tilfældet med en afsluttet underproces vil udførelse af en wait gøre det muligt for systemet at frigive ressourcerne associeret med underprocessen; hvis en wait ikke udføres, så bliver den afsluttede underproces i en »zombie«-tilstand (se NOTES nedenfor).
Hvis en underproces allerede har ændret tilstand, så returneres disse kald øjeblikkeligt. ellers blokerer de indtil en underproces ændrer tilstand eller en signalhåndtering afbryder kaldet (under antagelse af at systemkaldene ikke automatisk genstartes via flaget SA_RESTART for sigaction(2)). På resten af denne side vil en underproces, hvis tilstand har ændret sig og endnu ikke har modtaget en wait af et af disse systemkald blive kaldt for waitable.
wait() og waitpid()¶
Systemkaldet wait() suspenderer afviklingen af den kaldende tråd indtil en af dens underprocesser afsluttes. Kaldet wait(&wstatus) svarer til:
waitpid(-1, &wstatus, 0);
Systemkaldet waitpid() suspenderer afviklingen af den kaldende tråd indtil en underproces angivet af argumentet pid har ændret tilstand. Som standard venter waitpid() kun på afsluttede underprocesser, men denne opførsel kan ændres via argumentet options, som beskrevet nedenfor.
Værdien af pid kan være:
- < -1
- vent på nehver underproces hvis procesgruppe-id svarer til den absolutte værdi for pid.
- -1
- vent på enhver underproces.
- 0
- vent på enhver underproces hvis procesgruppe-id svarer til den kaldende proces på tidspunktet for kaldet til waitpid().
- > 0
- vent på underprocessen hvis proces-id svarer til værdien for pid.
Værdien af tilvalg er en OR af nul eller flere af de følgende konstanter:
- WNOHANG
- returner øjeblikkeligt hvis ingen underproces er afsluttet.
- WUNTRACED
- returnerer også hvis en underproces er stoppet (men ikke sporet via ptrace(2)). Status for traced-underprocesser, der er stoppet tilbydes selv om denne mulighed ikke er angivet.
- WCONTINUED (siden Linux 2.6.10)
- returnerer også hvis en stoppet underproces er blevet genoptaget ved levering af SIGCONT.
(For tilvalg kun for Linux, se nedenfor).
Hvis wstatus er NULL så lagrer wait() og waitpid() statusinformation i den int der peges på. Dette heltal kan inspiceres med de følgende makroer (der bruger selve heltallet som et argument, ikke en tekstsøger, som det gøres i wait() og waitpid()!):
- WIFEXITED(wstatus)
- returnerer true (sand) hvis underprocesen blev afsluttet normalt, det vil sige, ved at kalde exit(3) eller _exit(2), eller ved at returnere fra main().
- WEXITSTATUS(wstatus)
- returnerer afslutningsstatus for underprocessen. Denne består af de mindst signifikante 8 bit for argumentet status, som underprocessen angav i et kald til exit(3) eller _exit(2) eller som argumentet for et returudtryk i main(). Denne makro bør kun udrulles hvis WIFEXITED returnerede true (sand).
- WIFSIGNALED(wstatus)
- returnerer true (sand) hvis underprocessen blev afsluttet af et signal.
- WTERMSIG(wstatus)
- returnerer nummeret for signalet, der medførte at underprocessen blev afsluttet. Denne makro bør kun anvendes hvis WIFSIGNALED returnerede true (sand).
- WCOREDUMP(wstatus) // POSIX.1-2024
- returnerer true (sand) hvis underprocessen fremstillede et kernedump (se core(5)). Denne makro skal kun bruges hvis WIFSIGNALED returnede true.
- WIFSTOPPED(wstatus) // POSIX.1-2024
- returnerer true (sand) hvis underprocessen blev stoppet af en levering af et signal; dette er kun muligt hvis kaldet blev udført via WUNTRACED eller når underprocessen bliver sporet (se ptrace(2)).
- WSTOPSIG(wstatus)
- returnerer nummeret for signalet som fik underprocessen til at stoppe. Denne makro bør kun bruges hvis WIFSTOPPED returnerede true.
- WIFCONTINUED(wstatus)
- (siden Linux 2.6.10) returnerer true (sand) hvis underprocessen blev genoptaget ved levering af SIGCONT.
waitid()¶
Systemkaldet waitid() (tilgængelig siden Linux 2.6.9) tilbyder mere præcis kontrol over hvilke tilstandændringer for underprocesser, der skal ventes på.
Argumenterne idtype og id vælger underprocesserne, der skal ventes på, som følgende:
- idtype == P_PID
- Vent på underprocessen hvis proces-id matcher id.
- idtype == P_PIDFD (siden Linux 5.4)
- Vent for underprocessen refereret til af PID-fildeskriptoren angivet i id. (Se pidfd_open(2) for yderligere information om PID-fildeskriptorer).
- idtype == P_PGID
- Vent på en underproces hvis procesgruppe-id machter id. Siden Linux 5.4, hvis id er nul, så vent på eventuelle underprocesser, der er i den samme procesgruppe som kalderens procesgruppe på tidspunktet for kaldet.
- idtype == P_ALL
- Vent på en eventuel underproces; id bliver ignoreret.
Underprocestilstanden ændres til vent på er angivet af ORing en eller flere af de følgende flag i options:
- WEXITED
- Vent på underprocesser der er afsluttet.
- WSTOPPED
- Vent på underprocesser der er blevet stoppet af en signallevering.
- WCONTINUED
- Vent på (tidligere stoppet) underproces, der er blevet genoptaget ved levering af SIGCONT.
De følgende flag kan yderligere blive ORed i options:
- WNOHANG
- Som for waitpid().
- WNOWAIT
- Efterlad underprocessen i en ventende tilstand; et senere vente-kald kan bruges til igen at hente underprocessens statusinformation.
Ved succesfuld returnering udfylder waitid() de følgende felter i strukturen siginfo_t peget mod af infop:
- si_pid
- Proces-id for underprocessen.
- si_uid
- Det reelle bruger-id for underprocessen. (Dette felt er ikke angivet på de fleste implementeriner).
- si_signo
- Angiv altdi som SIGCHLD.
- si_status
- Enten afslutningsstatus for underprocessen, som angivet til _exit(2) (eller exit(3)), eller signalet der medførte at underprocessen blev afsluttet, stoppet eller fortsatte. Feltet si_code kan bruges til at bestemme hvordan dette felt skal fortolkes.
- si_code
- Angiv til en af: CLD_EXITED (underproces kaldt _exit(2)); CLD_KILLED (underproces dræbt af signal); CLD_DUMPED (underproces dræbt af signal, og dumpet kerne); CLD_STOPPED (underproces stoppet af signal); CLD_TRAPPED (sporet underproces er fanget); eller CLD_CONTINUED (underproces forsat af SIGCONT).
Hvis WNOHANG blev angivet i tilvalg og der ingen underprocesser var i en ventende tilstand, så returnerer waitid() 0 øjeblikkeligt og tilstanden for strukturen siginfo_t pegende mod infop afhænger af implementeringen. For (flytbart) at skelne dette tilfælde fra hvor en underproces var i en ventende tilstand, nulstil feltet si_pid før kaldet og tjek for en værdi forskellig fra nul i dettte felt efter kaldet returnerer.
POSIX.1-2008 Technical Corrigendum 1 (2013) tilføjer kravet at når WNOHANG er angivet i tilvalg og der er ingen underproces i en ventende tilstand, så bør waitid() nulstille felterne si_pid og si_signo for strukturen. På Linux og andre implementeringer, der overholder dette krav, er det ikke nødvendigt at nulstille feltet si_pid før waitid() kaldes. Alle implementeringer følger dog ikke POSIX.1-specifikationen på dette tidspunkt.
RETURVÆRDI¶
wait(): ved succes, returneres proces-id'et for den afsluttede underproces; ved fejl returneres -1.
waitpid(): ved succes returneres proces-id'et for underprocessen hvis tilstand har ændret sig; hvis WNOHANG blev angivet og en eller flere underprocesser angivet af pid findes, men endnu ikke har ændret tilstand, så returneres 0. Ved fejl returneres -1.
waitid(): returnerer 0 ved succes eller hvis WNOHANG var angivet og ingen underproces angivet af id endnu ikke har ændret tilstand; ved fejl returneres -1.
Ved fejl, angiver hvert af disse kald errno for at indikere fejlen.
FEJL¶
- EAGAIN
- PID-fildeskriptoren angivet i id er ikkeblokerende og processen den referer til er ikke afsluttet.
- ECHILD
- (for wait()) Den kaldende proces har ingen ej ventet for underproces.
- ECHILD
- (for waitpid() eller waitid()) Processen angivet af pid (waitpid()) eller idtype og id (waitid()) findes ikke eller er ikke en underproces af den kaldende proces. (Dette kan ske for ens egen underproces hvis handlingen for SIGCHLD er angivet til SIG_IGN. Se også afsnittet Linux Notes om tråde).
- EINTR
- WNOHANG var ikke angivet og et ej blokeret signal eller en SIGCHLD blev opfanget; se signal(7).
- EINVAL
- Argumentet tilvalg var ugyldigt.
- ESRCH
- (for wait() eller waitpid()) svarer pid til INT_MIN.
VERSIONER¶
C-bibliotek/kerne-forskelle¶
wait() er faktisk en biblioteksfunktion der (i glibc) er implementeret som et kald til wait4(2).
På nogle arkitekturer er det intet waitpid()-systemkald; i stedet for er denne grænseflade implementeret via en C-biblioteksomslagsfunktion, der kalder wait4(2).
Det rå systemkald waitid() anvender et femte argument, af typen struct rusage *. Hvis dette argument er forskellig fra NULL, så bruges det til at returnere information om ressourceforbrug for underprocessen, på samme måde som wait4(2). Se getrusage(2) for detaljer.
STANDARDER¶
POSIX.1-2024.
HISTORIK¶
SVr4, 4.3BSD, POSIX.1-2001.
NOTER¶
En underproces der afsluttes, men der ikke er blevet ventet på bliver en »zombie«. Kernen vedligeholder et minimum af information om zombieprocessen (PID, afslutningsstatus, information om ressourceforbrug) for at overprocessen senere kan udføre en wait for at få information om underprocessen. Så længe en zombie ikke fjernes fra systemet via en wait, så vil den bruge en plads i kerneprocestabellen og hvis denne tabel bliver fyldt, så vil der ikke længere kunne oprettes yderligere processer. Hvis en overproces afsluttes, så bliver dens (hvis nogen) »zombieprocesser« adopteret af init(1), (eller af den nærmeste »subreaper«-proces som defineret via brugen af prctl(2) PR_SET_CHILD_SUBREAPER-operationen); init(1) udfører automatisk en wait for at fjerne zombierne.
POSIX.1-2001 angiver at hvis dispositionen af SIGCHLD er angivet til SIG_IGN eller flaget SA_NOCLDWAIT er angivet for SIGCHLD (se sigaction(2)), så bliver underprocessen, der afsluttes, ikke en zombie og et kald til wait() eller waitpid() vil blokere indtil alle underprocesser er afsluttet, og så fejle med errno angivet til ECHILD. (Den oprindelige POSIX-standard efterlod opførelsen med at angive SIGCHLD til SIG_IGN uspecificeret. Bemærk at selvom standarddispositionen for SIGCHLD er »ignore« (ignorer), så medfører eksplicit angivelse af dispositionen til SIG_IGN forskellig behandling af zombieunderprocesser).
Linux 2.6 overholder POSIX-kravene. Linux 2.4 (og tidligere) gør dog ikke: hvis et wait()- eller waitpid()-kald laves mens SIGCHLD bliver ignoreret, så opfører kaldet sig som at SIGCHLD ikke blev ignoreret, det vil sige, kaldet blokeres indtil den næste underproces afsluttes og returnerer så proces-id'et og status for den underproces.
Linux-noter¶
I Linuxkernen er en kerneplanlagt tråd ikke en distinkt konstruktion fra en proces. I stedet er en tråd bare en proces, der oprettes via det Linux-unikke systemkald clone(2); andre rutiner såsom det flytbare kald pthread_create(3) implementeres via clone(2). Før Linux 2.4 var en tråd bare en speciel proces og som konsekvens kunne en tråd ikke vente på underprocessen i en anden tråd, selv om den sidstnævnte tilhører den samme trådgruppe. POSIX foreskriver dog sådan funktionalitet, og siden Linux 2.4 kan en tråd, og vil som standard, vente på underprocesser i andre tråde i den samme trådgruppe.
De følgende Linux-specifikke tilvalg er for brug med underproces oprettet via clone(2); de kan også, siden Linux 4.7, bruges med waitid():
- __WCLONE
- Vent kun på »klon«-underproces. Hvis udeladt så vent kun på »ikke-klon«-underproces. (En »klon«-underproces er en der ikke leverer et signal, eller et signal udover SIGCHLD til sin overproces ved afslutning). Dette tilvalg ignoreres hvis __WALL også er angivet.
- __WALL (siden Linux 2.4)
- Vent på alle underprocesser, uanset typen (»clone« eller »non-clone«).
- __WNOTHREAD (siden Linux 2.4)
- Vent ikke på underprocesser for andre tråde i den samme trådgruppe. Dette var standarden før Linux 2.4.
Siden Linux 4.7, antages flaget __WALL automatisk hvis underprocessen bliver ptraced.
FEJL¶
Jævnfør POSIX.1-2008 skal et program der kalder waitid() sikre at infop peger på en siginfo_t-struktur (dvs. at det er tekstsøger forskellig fra nul). På Linux, hvis infop er nul, så lykkes waitid() og returnerer proces-id'et for den ventet på-underproces. Programmer bør undgå at afhænge af denne inkonsistens, uden for standarden og unødvendige funktion.
EKSEMPLER¶
Det følgende program demonstrerer brugen af fork(2) og waitpid(). Programmet opretter en underproces. Hvis intet kommandolinjeargument leveres til programmet, så suspenderer underprocessen dens afvikling via pause(2), for at tillade at brugeren kan sende signaler til underprocessen. Ellers, hvis et kommandolinjeargument anvendes, så afsluttes underprocessen øjeblikkeligt, via heltalet angivet på kommandolinjen som afslutningsstatus. Overprocessen afvikler en løkke, der overvåger underprocessen via waitpid(), og bruger W*()-makroer beskrevet ovenfor til at analysere wait-statusværdien.
Den følgende skalsession demonstrerer brugen af programmet:
$ ./a.out & Child PID is 32360 [1] 32359 $ kill -STOP 32360 stopped by signal 19 $ kill -CONT 32360 continued $ kill -TERM 32360 killed by signal 15 [1]+ Done ./a.out $
Programkilde¶
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
int wstatus;
pid_t cpid, w;
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Kode afviklet af underproces */
printf("Child PID is %jd\n", (intmax_t) getpid());
if (argc == 1)
pause(); /* Vent på signaler */
_exit(atoi(argv[1]));
} else { /* Kode afviklet af overproces */
do {
w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
if (w == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(wstatus)) {
printf("exited, status=%d\n", WEXITSTATUS(wstatus));
} else if (WIFSIGNALED(wstatus)) {
printf("killed by signal %d\n", WTERMSIG(wstatus));
} else if (WIFSTOPPED(wstatus)) {
printf("stopped by signal %d\n", WSTOPSIG(wstatus));
} else if (WIFCONTINUED(wstatus)) {
printf("continued\n");
}
} while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
exit(EXIT_SUCCESS);
}
}
SE OGSŶ
_exit(2), clone(2), fork(2), kill(2), ptrace(2), sigaction(2), signal(2), wait4(2), pthread_create(3), core(5), credentials(7), signal(7)
OVERSÆTTELSE¶
Oversættere af denne manual til dansk Joe Hansen <joedalton2@yahoo.dk>
Denne oversættelse er gratis dokumentation; læs GNU General Public License version 3 eller nyere for ophavsretbetingelser. Der er INGEN ANSVAR.
Hvis du støder på fejl i oversættelsen af denne vejledning, skal du sende en besked til debian-l10n-danish@lists.debian.org.
| 8. februar 2026 | Linux man-pages 6.17 |