fork()!= 0和!fork()在进程创建中有什么区别

时间:2012-08-05 15:09:19

标签: c unix operating-system

目前,我正在基于UNIX的操作系统上做一些练习。我使用fork()系统调用来创建子进程,代码片段如下:

if(!fork())
{
   printf("I am parent process.\n");
}
 else
   printf("I am child process.\n");

此程序首先执行子进程,然后执行父进程。

但是,当我替换if(!fork()) by if(fork()!=0时,然后执行父块然后执行子块。我的问题是 - 在两种情况下结果应该是相同的还是有一些原因?在此先感谢!!

5 个答案:

答案 0 :(得分:3)

  • 没有保证执行的顺序。
  • 但是,if(!fork())if(fork()!=0)会在逻辑上给出相反的结果:如果fork()返回零,则!fork()为真,而{{1}是假的。

另外,从fork()的手册页:

  

成功时,子进程的PID在父进程中返回,并在子进程中返回0。失败时,在父项中返回-1,不创建子进程,并正确设置errno。

所以正确的检查是

fork()!=0
编辑:正如Wyzard所说,你一定要确保你以后也要使用pid。 (另外,将类型修改为pid_t而不是int。)

答案 1 :(得分:1)

你不应该真正使用其中任何一种,因为当孩子完成时,它将保持为僵尸,直到父母也完成。您应该在变量中捕获子项的pid并使用它来检索子项的退出状态:

pid_t child_pid = fork();
if (child_pid == -1)
{
  // Fork failed, check errno
}
else if (child_pid)
{
  // Do parent stuff...

  int status;
  waitpid(child_pid, &status, 0);
}
else
{
  // Child stuff
}

或者您应该使用“double-fork trick”将孩子与父母分开,这样孩子就不会像孩子一样等待父母检索其退出状态。

此外,您不能依赖在fork之后在父级之前执行的子级。您有两个进程,同时运行 ,无法保证相对执行顺序。它们可能轮流使用,也可以在不同的CPU内核上同时运行。

答案 2 :(得分:0)

!fork()fork() == 0的行为方式相同。

条件本身不能是执行顺序有任何不同的原因。 该过程被复制,这意味着孩子现在正在与父母竞争资源,包括CPU。操作系统调度程序决定哪个进程将获得CPU。

答案 3 :(得分:0)

父级和子级访问各自printf()语句的顺序未定义。很可能如果你要多次重复测试,两者的结果都是相似的,因为对于任何一个版本,有时候父进行打印,父进行打印次数。

答案 4 :(得分:0)

执行子进程和父进程的顺序由调度程序确定。它确定处理器执行每个进程的时间和持续时间。因此,输出的顺序可能因同一个程序代码而异。纯粹巧合的是,源代码的变化导致了输出序列的变化。 顺便说一句,你的printf应该是反过来的:如果fork()返回0,那么它是子进程,而不是父进程。

请参阅http://en.wikipedia.org/wiki/Fork_%28operating_system%29的代码示例。本文的德文版(http://de.wikipedia.org/wiki/Fork_%28Unix%29)包含一个示例输出和关于操作顺序的简短讨论。