1

我是 UNIX 编程的新手,我正在阅读僵尸进程以及如何使用 fork() 两次来避免它们。我从一本书中阅读了代码并尝试在我的系统上运行它。我使用的是 ubuntu 12.04。我运行了以下代码:

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

int main()
{
    pid_t pid;
    if(pid = fork() < 0)
        printf("Fork Error.!!!\n");
    else 
    if(pid == 0)
    {
        if((pid = fork()) < 0)
             printf("Fork2 Error.!!!\n");
        else 
             if(pid > 0)
                   exit(0);

        sleep(2);
        printf("Second Child, parent id: %d\n", getppid());
        exit(0);
    }
    if(waitpid(pid, NULL, 0) != pid)
        printf("Waitpid Error.!!!\n");

    exit(0);
}

我得到的输出如下:

Second Child, parent id: 1
Second Child, parent id: 1

这本书说这应该只打印一次,当我看到代码中发生的事情时,这也是我觉得应该发生的事情。我不明白为什么它会被打印两次。我在网上的很多地方都找到了这段代码,但找不到能解释这一点的东西。欢迎任何帮助。谢谢。!!

4

4 回答 4

5

main 中的第二行代码 - 缺少括号pid = fork()

if( ( pid = fork() ) < 0){
于 2012-08-12T18:34:04.710 回答
5

在这一行:

if(pid = fork() < 0)

您应该在零件周围添加括号pid = fork(),就像您为另一个叉子所做的那样。您正在分配fork() < 0to的结果pid。只要分叉没有失败,这意味着pid在第一个分叉的父和子中都变为 0,因此您将获得 2 个运行子分支的进程(每个进程都创建自己的子分支)并且没有运行waitpid.

于 2012-08-12T18:37:32.337 回答
1

请检查此链接。它说:

当使用 fork(),尤其是 vfork() 时,exit() 和 _exit() 之间存在一些显着差异。

...

在 fork() 的子分支中,使用 exit() 通常是不正确的,因为这会导致 stdio 缓冲区被刷新两次,并且临时文件被意外删除。

这对我来说很有意义,您需要相应地更新代码以获得预期的结果。

于 2012-08-12T18:44:31.620 回答
-1

pid_t pid;
if(pid = fork() < 0)
printf("Fork Error.!!!\n");

将创建一个线程。所以目前我们有两个线程主线程和子线程。排队

if(pid == 0)

您正在检查子线程中的当前线程。您再次创建了一个新线程

if((pid = fork()) < 0)
     printf("Fork2 Error.!!!\n");
else if(pid > 0)        //Do nothing if this is parent thread.
     exit(0);

所以现在你有线程在运行,它会执行

printf("Second Child, parent id: %d\n", getppid());

因此,您将消息打印两次。

于 2012-08-12T18:30:44.477 回答