Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   wait.3p    ( 3 )

подождите, пока дочерний процесс остановится или завершится (wait for a child process to stop or terminate)

Примеры (Examples)

Waiting for a Child Process and then Checking its Status
       The following example demonstrates the use of waitpid(), fork(),
       and the macros used to interpret the status value returned by
       waitpid() (and wait()).  The code segment creates a child process
       which does some unspecified work. Meanwhile the parent loops
       performing calls to waitpid() to monitor the status of the child.
       The loop terminates when child termination is detected.

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> ...

pid_t child_pid, wpid; int status;

child_pid = fork(); if (child_pid == -1) { /* fork() failed */ perror("fork"); exit(EXIT_FAILURE); }

if (child_pid == 0) { /* This is the child */ /* Child does some work and then terminates */ ...

} else { /* This is the parent */ do { wpid = waitpid(child_pid, &status, WUNTRACED #ifdef WCONTINUED /* Not all implementations support this */ | WCONTINUED #endif ); if (wpid == -1) { perror("waitpid"); exit(EXIT_FAILURE); }

if (WIFEXITED(status)) { printf("child exited, status=%d\n", WEXITSTATUS(status));

} else if (WIFSIGNALED(status)) { printf("child killed (signal %d)\n", WTERMSIG(status));

} else if (WIFSTOPPED(status)) { printf("child stopped (signal %d)\n", WSTOPSIG(status));

#ifdef WIFCONTINUED /* Not all implementations support this */ } else if (WIFCONTINUED(status)) { printf("child continued\n"); #endif } else { /* Non-standard case -- may never happen */ printf("Unexpected status (0x%x)\n", status); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); }

Waiting for a Child Process in a Signal Handler for SIGCHLD The following example demonstrates how to use waitpid() in a signal handler for SIGCHLD without passing -1 as the pid argument. (See the APPLICATION USAGE section below for the reasons why passing a pid of -1 is not recommended.) The method used here relies on the standard behavior of waitpid() when SIGCHLD is blocked. On historical non-conforming systems, the status of some child processes might not be reported.

#include <stdlib.h> #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h>

#define CHILDREN 10

static void handle_sigchld(int signum, siginfo_t *sinfo, void *unused) { int sav_errno = errno; int status;

/* * Obtain status information for the child which * caused the SIGCHLD signal and write its exit code * to stdout. */ if (sinfo->si_code != CLD_EXITED) { static char msg[] = "wrong si_code\n"; write(2, msg, sizeof msg - 1); } else if (waitpid(sinfo->si_pid, &status, 0) == -1) { static char msg[] = "waitpid() failed\n"; write(2, msg, sizeof msg - 1); } else if (!WIFEXITED(status)) { static char msg[] = "WIFEXITED was false\n"; write(2, msg, sizeof msg - 1); } else { int code = WEXITSTATUS(status); char buf[2]; buf[0] = '0' + code; buf[1] = '\n'; write(1, buf, 2); } errno = sav_errno; }

int main(void) { int i; pid_t pid; struct sigaction sa;

sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = handle_sigchld; sigemptyset(&sa.sa_mask); if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(EXIT_FAILURE); }

for (i = 0; i < CHILDREN; i++) { switch (pid = fork()) { case -1: perror("fork"); exit(EXIT_FAILURE); case 0: sleep(2); _exit(i); } }

/* Wait for all the SIGCHLD signals, then terminate on SIGALRM */ alarm(3); for (;;) pause();

return 0; /* NOTREACHED */ }