僵尸进程的产生和SIGCHLD信号

核心句子

子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自 定义SIGCHLD信号的处理函数。

僵尸进程的产生:

#include "head.h"
#include <unistd.h>
#include <signal.h>


int main()
{
    key_t key = ftok(".",1);

    pid_t pid = fork();
    if( pid > 0)
    {
        while(1)
        {
            printf("I am  father\n");
            sleep(1);
        }
    }
    else if(pid == 0)
        printf("I am child\n");
    else
        perror("fork()");
}

这里写图片描述
优先选择#ps -lA | grep a.out

这里写图片描述

SIGCHLD建立信号处理程序

当SIGCHLD信号正在处理一个终止的子进程时,如果有两个子进程同时终止,那么就产生了两个SIGCHLD信号,父进程只可以捕获一个。

结果是父进程的SIGCHLD信号处理程序每次只调用一次wait()。这样就一定会产生僵尸进程

使用for循环产生10个子进程,十个子进程都是僵尸进程

#include "head.h"
#include <unistd.h>
#include <signal.h>

int handler(int s)
{
    wait();
}

int main()
{
    key_t key = ftok(".",1);

    signal(SIGCHLD,handler);
    int i ;
    for(i = 0;i<10;i++)
    {
        pid_t pid = fork();

        if (pid == 0)
            {
                printf("i am child\n");
                sleep(1);
                exit(0);
            }
        else if(pid < 0)
            perror("fork():");
    }
    while(1)
    {
        printf("让程序在这里死循环,然后观察后台进程\n");
        sleep(1);
    }
}

产生了七个僵尸进程,SIGCHLD只处理掉了三个

这里写图片描述

处理方案

int handler(int s)
{
    while(waitpid(-1,NULL,WNOHANG) > 0)
    {
        continue; 
    }
}

这里写图片描述

关于waitpid () 和 wait()的解释请看下一篇博客

猜你喜欢

转载自blog.csdn.net/csdn_kou/article/details/81057339