僵尸进程处理方法

僵尸进程:本质是进程描述符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;

posted @ 2015-06-25 21:48  kkshaq  阅读(1589)  评论(0编辑  收藏  举报