之前的内容里我们用wait来处理已经终止的子进程,waitpid的功能和wait类似,但也有区别。
wait和waitpid的函数模型:
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
返回值:若成功则返回进程的ID, 出错则返回0或者-1
相同点
函数wait和waitpid均返回两个值,已经终止进程的pid,以及通过statloc指针返回的子进程的终止状态(一个整数)。我们可以调用三个宏来检查终止状态,来辨别子进程是否正常终止、由某个信号杀死还是仅仅由作业控制停止而已。另外有些宏接着获取子进程退出状态、杀死子进程的信号值或者停止子进程的作业信号控制值。
不同点:
如果调用wait的进程没有已终止的子进程,不过有一个或者多个子进程正在运行,那么那么wait将阻塞到现有子进程第一个终止为止。
waitpid函数就等待进程和是否阻塞给我们了更多控制权。首先,pid参数允许我们指定想等待的进程pid,值-1表示等待第一个终止的子进程。其次。options参数允许我们指定附加选项,如WNOHANG,它告知内核在没有终止子进程的时候不要阻塞。
处理僵尸进程
wait版:
#include <unp.h>
void
sig_chld(int signo)
{
pid_t pid;
int stat;
pid = wait(&stat);
printf("child %d terminated\n", pid);
return;
}
waitpid版本:
#include <unp.h>
void
sig_chld(int signo)
{
pid_t pid;
int stat;
while( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return;
}
其中 uno.h 参考文章 http://blog.csdn.net/thinkerleo1997/article/details/75631157
在处理僵尸进程的时候,只需要在fork前加入代码signal(SIGCHLD, sig_child);
即可。
但是处理多个产生的僵尸进程时,wait的功能不足以处理所有的僵尸进程,此时就要用到waitpid函数。