Wait的背景
当子进程退出的时候,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止)
子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程,它只保留最小的一些内核数据结构,以便父进程查询子进程的退出状态。
父进程查询子进程的退出状态可以用wait/waitpid函数
#include <sys/types.h>#include <sys/wait.h>pid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);Waitpid_t wait(int *status);
当我们用fork启动一个进程时,子进程就有了自己的生命,并将独立地运行。有时,我们需要知道某个子进程是否已经结束了,这样我们可以通过wait安排父进程在子进程结束之后。
status:该参数可以获得你等待子进程的信息
返回值:
onsuccess,returnstheprocessIDoftheterminatedchild;onerror,-1isreturned.
特征:
1.wait系统调用会使父进程暂停执行,直到它的任意一个(并不是所有的)子进程结束为止。
2.返回的是子进程的PID,它通常是已经结束了的子进程;
3.状态信息允许父进程判定子进程的退出状态,即从子进程的main函数返回的值或子进程中exit/_exit语句的退出码。
4.如果status不是一个空指针,状态信息将被写入它指向的位置
//示例int main(){pid_t pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0){cout << "In Child, pid = " << getpid() << endl;sleep(5);exit(10);}int status;int returnPid = wait(&status);//两个pid的值相同,但是status的值根本不是10cout << "In Parent, returnPid = " << returnPid<< ", status = " << status << endl;}
宏定义
描述
WIFEXITED(status)
WEXITSTATUS(status)
如果子进程正常结束,返回一个非零值
如果WIFEXITED非零,返回子进程退出码
WIFSIGNALED(status)
WTERMSIG(status)
子进程因为捕获信号而终止,返回非零值
如果WIFSIGNALED非零,返回信号代码
WIFSTOPPED(status)
WSTOPSIG(status)
如果子进程被暂停,,返回一个非零值
如果WIFSTOPPED非零,返回一个信号代码
//示例void printStatus(int status){if (WIFEXITED(status)){cout << "normal termination, exit status = " << WEXITSTATUS(status) << endl;}else if (WIFSIGNALED(status)){cout << "abnormal termination, signal number = " << WTERMSIG(status);#ifdef WCOREDUMPif (WCOREDUMP(status))cout << " (core file generated)" << endl;#elsecout << endl;#endif // WCOREDUMP}else if (WIFSTOPPED(status)){cout << "child stopped, status number = " << WSTOPSIG(status) << endl;}else{cout << "Unknow Stop!" << endl;}}//测试代码int main(){pid_t pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0)exit(7);int status;if (wait(&status) == -1)err_exit("first wait error");printStatus(status);pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0)abort();if (wait(&status) == -1)err_exit("first wait error");printStatus(status);pid = fork();if (pid == -1)err_exit("fork");else if (pid == 0)status /= 0;if (wait(&status) == -1)err_exit("first wait error");printStatus(status);return 0;}
Pid:Thevalueofpidcanbe:
<-1meaningwaitforanychildprocesswhoseprocessgroupIDisequaltotheabsolutevalueofpid.
-1meaningwaitforanychildprocess(任一子进程).
0meaningwaitforanychildprocesswhoseprocessgroupIDisequaltothatofthecallingprocess(与调用者进程同在一个组的进程).
>0meaningwaitforthechildwhoseprocessIDisequaltothevalueofpid.
status:如果不是空,会把状态信息写到它指向的位置(同wait)
options:允许改变waitpid的行为,最有用的一个选项是WNOHANG,它的作用是防止waitpid把调用者的执行挂起
返回值:
如果成功返回等待子进程的ID,失败返回-1
wait与waitpid的区别:
1.在一个子进程终止前,wait使其调用者阻塞,而waitpid有一选择项,可使调用者不阻塞。
2.waitpid并不等待第一个终止的子进程:它有若干个选择项,可以控制它所等待的特定进程。
3.wait函数相当于是waitpid函数的一个特例。
waitpid(-1,&status,0);
僵尸进程(如果不等待…)
当一个子进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行或者父进程调用了wait才告终止。
我们可以失望,但不能盲目。