5

我想知道以下代码是否可以创建僵尸:

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

int main(){
    int i=1;
    pid_t p;
    p = fork();
    i++;
    if(p!=0){
        waitpid(p, NULL, 0);
    }
    printf("%d\n",i);
    return 0;
}

因此,父进程调用子进程的waitpid,如果子进程还没有退出,它会立即返回。所以,到目前为止,还没有僵尸出现。但是,如果孩子之前退出

返回0;
命令这将是一个僵尸呢?我实际上对此感到困惑。waitpid 是否应该是程序终止前的最后一行代码?任何帮助,将不胜感激。谢谢!

4

2 回答 2

6

孩子只有在结束时才会变成僵尸,只要它自己还活着父母就不会打电话。wait*()

在父进程也结束的那一刻,子进程被init负责调用wait*()子进程的进程收割,所以它最终会结束并离开僵尸状态并从进程列表中消失。

要使您的示例代码中创建的孩子成为僵尸,请修改代码,例如:

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

int main(void) 
{
    pid_t p = fork();

    if (p != 0) 
    {
        waitpid(p, NULL, 0); /* See if the child already had ended. */
        sleep(1); /* Wait 1 seconds for the child to end. And eat away the SIGCHLD in case if arrived. */
        pause(); /* Suspend main task. */
    }
    else
    {
        sleep(3); /* Just let the child live for some tme before becoming a zombie. */
    }

    return 0;
}

由于以下两个事实:

  • 孩子睡了 3 秒,所以父母的电话waitpid()很可能总是失败
  • 的默认处理SIGCHLD是忽略它。

上面的代码实际上是一样的:

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

int main(void) 
{
    pid_t p = fork();

    if (p != 0) 
    {
        pause(); /* Suspend main task. */
    }
    else
    {
        sleep(3); /* Just let the child live for some tme before becoming a zombie. */
    }

    return 0;
}
于 2013-12-15T21:47:13.787 回答
0

我找到了一种创建僵尸进程并使用 ps -e 对其进行测试的简单方法

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void  main()
{
    pid_t pid;
    pid = fork();
    //parent sleeps while the child has exited
    //not an orphan since parent still alive
    //child will be still present in process table
    if(pid==0)
    {//child
        exit(0);
    }
    else
    {//parent
        sleep(15);
    }
}

在 15 秒内运行 ps -e ......你会看到

6454 pts/2 00:00:00 a.out <已失效>

于 2016-09-08T11:20:01.830 回答