标签:
僵尸进程:本质是进程描述符task_struct;
维护子进程的状态,包括子进程ID,终止状态以及进程的资源利用情况(cpu时间,内存)
int wait(int*stat_loc):成功之后返回终止子进程的pid,失败返回-1,并设置errno
1、wait调用堵塞进程直到有任一一个子进程终止,则立刻返回,返回值为此终止进程的pid
2、如果wait调用的时候,有多个字进程终止,wait()选择任一一个子进程,通过pid识别
3、 如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。、
pid_t waitpid(pid_t pid,int * status,int options);
waitpid(-1,null,0)等价于wait(NULL)
pid==-1:等待任一子进程
pid==0,等待进程组id和调用进程的组id相同的任意子进程
pid>0,等待进程id为pid的子进程
pid<-1,等待进程组id等于pid绝对值的任意进程
若有很多子进程在waitpid()之前已经终止,则随机选择其中一个并立刻返回
如果我们调用waitpid的时候不想堵塞,可以设置options
options:包括0,WNOHANG,WUTRACED
如果取 WNOHANG,我们调用waitpid的时候,就不堵塞。直接返回pid或者0
所以多出的功能包括:
1、waitpid提供wait()非堵塞版本,waitpid(child_pid,null,WNOHANG),用来查看指定的子进程有没有终止,如果没有终止,并不是堵塞,而是返回0.
2、waitpid可以等待特定的进程终止
在僵尸进程处理过程中:
wait()函数的不足:由于信号不排队,所以我们父进程调用wait()之时,别的子进程(假设有4个)终止发送的SIGCHLD信号都被堵塞(同一信号在信号处理函数是被堵塞的)
信号处理函数结束之后,只有一个SIGCHLD被递交给父进程,再次调用wait函数,则会留下3个僵尸进程
如果在wait()之前,5个子进程都在信号处理程序执行之前产生,则已经是僵尸进程了,只随机选择一个,剩下4个僵尸进程
1、这会导致由于问题的不确定性。
2、僵尸进程不能处理完全
以上的问题,可以通过while循环调用wait解决,但是由于wait是堵塞的,所以可能会导致过长的wait等待
基于wait不能非堵塞调用,所以我们只能选择waitpid,这是关键原因
void sig_chld(int signo){
pid_t pid;
int stat;
while(pid=waitpid(-1;&stat,WNOHANG))>0)
{}
return;
}
标签:
原文地址:http://www.cnblogs.com/kkshaq/p/4601017.html