我是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
这本书说这应该只打印一次,当我看到代码中发生的事情时,这也是我觉得应该发生的事情。我不明白为什么它会被打印两次。我在网上的许多地方发现了这个代码,但无法解释这个问题。欢迎任何帮助。谢谢!
答案 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());
因此,您将收到两次打印的消息。