2次使用fork避免产生僵尸进程和不去处理SIGCHLD信号

1.如下代码所示

#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
        pid_t child = fork();

        if( child == -1 ) { //error
                printf("
fork child error.");
                exit(0);
        } else if(child == 0){
                //exit(0);
                if ((child = fork()) < 0)
                        printf("fork error
");
                else if (child > 0)
                {
//                      sleep(3);
                        exit(0);
                }
                sleep(5);
                printf("second child,parent pid %d
",getppid());
                exit(0);
        }
//      sleep(3);       
        if (waitpid(child,NULL,0) != child)
                printf("waitpid error
");
        sleep(10);
        exit(0);
        //sleep(600);

}

1个终端使用gcc -g test.c -o test 生成test程序后,准备执行。

另1个终端不断敲击命令ps lfx | grep test,其中第3列显示pid,第4列显示ppid。

可以看到另1个终端显示:

0 0 28787 20574 20 0 3920 340 hrtime S+ pts/1 0:00 | \_ ./test
0 0 28792 20817 20 0 103248 828 pipe_w S+ pts/2 0:00 \_ grep test
1 0 28789 1 20 0 3920 140 hrtime S+ pts/1 0:00 ./test

其中第3行为我们第二次fork的子进程,其ppid已为1(即init进程)

第1行的test进程为主进程在sleep(10),达到了咱们的目的。

2.这里主要探讨下waitpid在这里的用法

作用:回收第1个fork产生的子进程,这里的代码显示这个子进程产生后马上调用exit。

3.疑惑:fork函数后父子进程的先后执行顺序不定,waitpid总能成功收回吗?

在这里做2个实验,

第一次把代码中第20行sleep(3);解除注释,运行,观察结果。(主进程waitpid执行后产生僵尸进程)

第二次把代码中第27行sleep(3);解除注释,运行,观察结果。(主进程waitpid执行前产生僵尸进程)

可见2次实验中最后都没有僵尸进程,说明都成功收回了。

第2次实验中僵尸进程大概存在了3秒左右,是由于第27行的sleep(3).

可见次代码中主进程的waitpid总能把第一次fork的子进程成功收回。

原文地址:https://www.cnblogs.com/dodng/p/4383912.html