5 wait和waitpid函数
当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。
5.1调用wait或waitpid的进程可能会:
阻塞(如果其子进程都还在运行)
带子进程的终止状态立即返回
出错立即返回
5.2wait和waitpid的区别:
在一个子进程终止前, wait 使其调用者阻塞,而 waitpid 有一选择项,可使调用者不阻塞。
waitpid并不等待第一个终止的子进程—它有若干个选择项,可以控制它所等待的进程。
代码示例:
#include "ourhdr.h" #include <sys/wait.h> void pr_exit(int status) { if (WIFEXITED(status)) printf("normal termination, exit status = %d\n", WEXITSTATUS(status)); else if (WIFSIGNALED(status)) printf("abnormal termination, signal number = %d%s\n", WTERMSIG(status), #ifdef WCOREDUMP WCOREDUMP(status) ? " (core file generated)" : ""); #else ""); #endif else if (WIFSTOPPED(status)) printf("child stopped, signal number = %d\n", WSTOPSIG(status)); } int main(void) { pid_t pid; int status; if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ exit(7); if (wait(&status) != pid) /* wait for child */ err_sys("wait error"); pr_exit(status); /* and print its status */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ abort(); /* generates SIGABRT */ if (wait(&status) != pid) /* wait for child */ err_sys("wait error"); pr_exit(status); /* and print its status */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid == 0) /* child */ status /= 0; /* divide by 0 generates SIGFPE */ if (wait(&status) != pid) /* wait for child */ err_sys("wait error"); pr_exit(status); /* and print its status */ exit(0); }
打印结果:
[[email protected] fork]# gcc wait.c wait.c: In function ‘main’: wait.c:48: warning: division by zero [[email protected] fork]# ./a.out normal termination, exit status = 7 abnormal termination, signal number = 6 abnormal termination, signal number = 8
5.3如果一个进程要 f o r k一个子进程,但不要求它等待子进程终止,也不希望子进程处于僵死状态直到父进程终止,实现这一要求的诀窍是调用 f o r k两次。
代码示例:
#include "ourhdr.h" #include <sys/wait.h> #include <sys/types.h> int main(void) { pid_t pid; if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { /* first child */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid > 0) exit(0); /* parent from second fork == first child */ /* * We‘re the second child; our parent becomes init as soon * as our real parent calls exit() in the statement above. * Here‘s where we‘d continue executing, knowing that when * we‘re done, init will reap our status. */ sleep(2); printf("second child, parent pid = %d\n", getppid()); exit(0); } if (waitpid(pid, NULL, 0) != pid) /* wait for first child */ err_sys("waitpid error"); /* * We‘re the parent (the original process); we continue executing, * knowing that we‘re not the parent of the second child. */ exit(0); }
打印结果:
[[email protected] fork]# ./a.out [[email protected] fork]# second child, parent pid = 1
6 wait3 和wait4函数
时间: 2024-10-05 05:06:59