当子进程先于父进程退出时,如果父进程没有调用wait和waitpid函数,子进程就会进入僵死状态。
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
----------------------------------------------------------------------------------------------------------
The wait() system call suspends execution of the calling process until one of its children terminates. The call wait(&status) is equivalent to:
waitpid(-1, &status, 0);
wait函数使父进程暂停执行,直到他的一个子进程结束为止。返回值为结束的子进程的进程ID
参数status存放子进程的退出码,即子进程main函数的返回值,或者子进程exit函数的参数。
如果status不是一个空指针,状态信息将被写入它指向的变量。
在手册中有解读进程退出状态的宏,举例:
WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().
----------------------------------------------------------
The waitpid() system call suspends execution of the calling process until a child specified by pid argument has changed state. By default, waitpid() waits only for terminated children, but
this behavior is modifiable via the options argument, as described below.
参数说明:
pid:指明要等待的子进程的进程ID
< -1 meaning wait for any child process whose process group ID is equal to the absolute value of pid.
-1 meaning wait for any child process.
0 meaning wait for any child process whose process group ID is equal to that of the calling process.
> 0 meaning wait for the child whose process ID is equal to the value of pid.
status:
options:允许用户改变waitpid的行为:
The value of options is an OR of zero or more of the following constants:
WNOHANG return immediately if no child has exited.
WUNTRACED also return if a child has stopped (but not traced via ptrace(2)). Status for traced children which have stopped is provided even if this option is not specified.
WCONTINUED (since Linux 2.6.10)
also return if a stopped child has been resumed by delivery of SIGCONT.
waitpid提供了一个wait函数的非阻塞版本,有时候希望取得一个子进程的状态,但不想使父进程阻塞,把options设置为WNOHANG
waitpid(*, *,WNOHANG );他可以使得调用者不阻塞。
如果没有任何子进程的进程调用了wait函数,会立即出错返回。
测试程序:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { int exit_code; int k; char* msg; pid_t pid; pid = fork(); if (pid < 0) { exit(-1); } else if (0 == pid) { k = 5; msg = "child is running"; exit_code = 33; printf("child's pid:%d ", getpid()); } else { exit_code = 0; } if ( pid != 0)//父进程执行 { int stat_val; pid_t pid; pid = wait( &stat_val ); printf("child process has exited,pid=%d ", pid); if ( WIFEXITED(stat_val) ) { printf("child exited with code:%d ", WEXITSTATUS(stat_val)); } else { printf("child process exit abnormally "); } } else//子进程执行 { while(k-- > 0) { puts( msg ); sleep(1); } } exit(exit_code); }
说明:
父进程调用wait之后会挂起,直到子进程结束为止。宏WEXITSTATUS获取子进程的退出码