为什么线要打印两次?

时间:2012-08-12 18:17:18

标签: c unix fork zombie-process

我是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 个答案:

答案 0 :(得分:5)

主要代码的第二行 - pid = fork()

周围缺少括号
if( ( pid = fork() ) < 0){

答案 1 :(得分:5)

在这一行:

if(pid = fork() < 0)

您应该在pid = fork()部分周围添加括号,就像您对其他分叉所做的那样。您要将fork() < 0的结果分配给pid。只要fork没有失败,这意味着pid在第一个fork的父级和子级中都变为0,所以你得到2个运行子分支的进程(每个进程创建一个子进程)它自己)并没有运行waitpid

答案 2 :(得分:1)

请检查link。它说:

  

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

     

...

     

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

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

答案 3 :(得分:-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());

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