创建僵尸进程的麻烦

时间:2014-01-23 18:54:37

标签: c linux process

我是一名正在学习编程的学生,正致力于创建和关闭流程。我能够创建这个从Bash获取参数的程序,argv[1]是进程将创建的子进程数。 argv[2]确定这些孩子中的哪一个创造了另一个孩子。现在我希望让argv[3]将这个数量的子进程(从argv[1])变为僵尸。我还必须以某种方式设置“故障安全”,以便孩子在成为僵尸之前首先处理孙子exit()

我成功地使前两个论点起作用。

代码为:

int main(int argc, char *argv[])
{
    int i, antal, grandchild; pid_t pid, pid2;
    antal=atoi(argv[1]);
    grandchild=atoi(argv[2]);
    printf("antal=%d.\n grandchild=%d\n\n", antal,grandchild);
    for(i=0; i<antal; i++)
    {
        pid=fork();
        switch(pid)
        {
            case -1:
                fprintf(stderr, "Fork Failed!");
                break;

            case 0:
                printf("Child process: %d.\n", getpid());
                sleep(1);
                if(i+1==grandchild)
                    pid2=fork();
                    if(pid2==0)
                    {
                        printf("I am the grandchilde with PID: %d.\n",getpid());
                        sleep(5);
                        exit(0);
                    }
                wait(0);
                exit(0);
                break;

            default: printf("Parent process with PID: %d\n", getpid());
                wait(0);
                break;

        }
    }
}

我无法理解如何做到这一点。我已经6个月了,所以我没有丰富的编程技巧。非常感谢您对该主题的任何帮助或提示。对于任何有关此问题的良好信息的网站,我也将非常感激。

此外,交换机被认为是控制fork()返回值的最友好选项吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

所有进程都会在exit()之后成为僵尸;一旦他们的父进程wait()为他们,他们将被删除。如果父进程终止,它们将由init进程继承,除了在完成初始化系统时在循环中调用wait()之外,它基本上什么都不做。所以,只要你的进程退出,所有你的僵尸就会很快被init放到他们的坟墓里。一旦您的孩子退出(或拨打wait(),就像在您的计划中一样),您的孙子将不再是僵尸。

因此,要查看ps -a中的僵尸,您必须在程序结束时添加类似sleep(1000)的内容,以防止其退出。

你的孩子,有孙子,也不应该wait()。尝试像

这样的东西
while (kill(pid, 0)!=-1)
    sleep(1);

等待进程退出(使用0号信号进行终止什么都不做,但如果进程不存在则会失败。由于其他原因可能会失败,但这些通常不适用于此处) 。

不是你在这里尝试做的不是教育目的,但是如果你在“真正的”程序中尝试这个,那么unix守护进程会在你的睡眠中降临到你身上并以你不这样做的方式困扰着你甚至想要考虑一下。

答案 1 :(得分:0)

除了Guntram Blohm写的内容之外,你显然已经忘记了括号:

            if(i+1==grandchild)
                pid2=fork();
                if(pid2==0)
                {
                    printf("I am the grandchilde with PID: %d.\n",getpid());
                    sleep(5);
                    exit(0);
                }

(具有适当选项的优秀编译器会警告pid2可能未初始化。)

你可以写

            if (i+1==grandchild)
                if (fork()==0)
                {
                    printf("I am the grandchilde with PID: %d.\n",getpid());
                    sleep(5);
                    exit(0);
                }

代替。