有关defunct进程(僵尸进程)的处理原则

僵尸进程:就是已经结束了的进程,但是没有从进程表中删除。太多了会导致进程表里面条目满了,进而导致系统崩溃,倒是不占用其他系统资源。
僵尸进程的查看:
ps -ef
出现:
root     13028 12956 0 10:51 pts/2    00:00:00 [ls] <defunct>
最后有defunct的标记,就表明是僵尸进程。

产生的原因:
每个Linux进程在进程表里都有一个进入点(entry),核心程序执行该进程时使用到的一切信息都存储在进入点。当用ps命令察看系统中的进程信息时,看到的就是进程表中的相关数据。当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。当这个进程走完了自己的生命周期后,它会执行exit()系统调用,此时原来进程表中的数据会被该进程的退出码(exit code)、执行时所用的CPU时间等数据所取代,这些数据会一直保留到系统将它传递给它的父进程为止。由此可见,defunct进程的出现时间是在子进程终止后,但是父进程尚未读取这些数据之前。

产生的例程:
#include "sys/types.h"
#include "sys/wait.h"

#include "stdio.h"
#include "unistd.h"

int main(int argc, char* argv[])
{
while(1)
{
    pid_t chi = fork();
    if(chi == 0)
    {
      execl("/bin/ls",NULL);
    }

    sleep(2);
}
}

对付这种的方法:
外部的方法:
执行pstree,看到:
     |-sshd-+-sshd---bash
     |      |-sshd---sftp-server
     |      `-sshd-+-bash---vi
     |             |-bash---myfork---2*[ls]
也就是主进程是myfork
将myfork干掉就可以了

编程的方法:
1、主进程等待子进程
#include "sys/types.h"
#include "sys/wait.h"

#include "stdio.h"
#include "unistd.h"

int main(int argc, char* argv[])
{
while(1)
{
    pid_t chi = fork();
    if(chi == 0)
    {
      execl("/bin/ls",NULL);
    }

    int status;
    wait(&status);
    sleep(2);
}
}

也就是加上了wait
2、在主进程里面补充对child 退出的signal的处理:
void sig_child(int signo){
       pid_t   pid;
       int   stat,i;
       while((pid = waitpid(-1, &stat, WNOHANG)) > 0);
       return;
}

      signal(SIGCHLD,sig_child);

猜你喜欢

转载自shithanwa.iteye.com/blog/1044037
今日推荐