c - 创建僵尸进程的麻烦

标签 c linux process

我是一名学生,目前正在学习编程,并且致力于创建和关闭流程。我能够创建这个从 Bash 获取参数的程序,argv[1] 是进程将创建的子进程的数量。 argv[2] 确定这些 child 中的哪一个创建了另一个 child 。现在我想让 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 个月的类(class),所以我没有广泛的编程技能。非常感谢有关该主题的任何帮助或提示。我也将非常感谢任何提供有关此事的有用信息的网站。

开关是否也被认为是控制 fork() 返回值的阅读最友好的选项?

提前致谢。

最佳答案

所有进程在exit()后都会变成僵尸;一旦它们的父进程为它们处理wait(),它们就会被删除。如果父进程死亡,它们将由 init 进程继承,它基本上除了在完成系统初始化后在循环中调用 wait() 之外什么都不做。因此,一旦您的进程退出,所有您的僵尸将很快被 init 埋葬。一旦您的 child 退出(或调用 wait(),就像在您的程序中一样),您的孙子也将不再是僵尸。

所以要在 ps -a 中看到僵尸,您必须在程序末尾放置类似 sleep(1000) 的内容以防止它退出。

您的 child 有孙子,也不应该wait()。尝试类似的东西

while (kill(pid, 0)!=-1)
    sleep(1);

等待进程退出(用信号号 0 杀死根本不执行任何操作,但如果进程不存在则失败。它也可能因其他原因而失败,但这些通常不适用于此处) .

并不是说你在这里尝试做的事情可以用于教育目的,但如果你在“真实”程序中尝试过,unix 守护进程会在你睡梦中降临并以你不会的方式困扰你甚至想想想。

关于c - 创建僵尸进程的麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21316970/

相关文章:

c - 当我定义数组时真正发生了什么

c - 在 ChessBoard C 代码中遍历骑士

c - 实现无限循环时,使用 while(1) vs for(;;) vs goto(在 C 中)有区别吗?

c - 对于套接字,哪一侧负责大部分工作?

linux - 在 Linux 中循环遍历文件夹?

c: 将 malloc 的数组元素设置为 NULL(无效写入)

c++ - 在 Linux 上进行 3d 编程应该使用什么环境?

windows - 在unix中获取windows中bat文件的返回值?

javascript - Node.js 在一个端口上运行两个应用程序

c# - 使用 Process.Start 启动 WPF 应用程序