1

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

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

而这个程序先执行子进程,再执行父进程。

但是,当我替换if(!fork()) by if(fork()!=0) 然后父块然后子块执行。这里我的问题是 - 结果是否应该在这两种情况下是相同的,或者这背后有什么原因?提前致谢!!

4

5 回答 5

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

此外,从 fork() 的手册页中:

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

所以正确的检查是

pid_t pid = fork();
if(pid == -1) {
     // ERROR in PARENT
} else if(pid == 0) {
     // CHILD process
} else {
     // PARENT process, and the child has ID pid
}

编辑:正如 Wyzard 所说,您绝对应该确保稍后也使用 pid。(另外,将类型固定为 pid_t 而不是 int。)

于 2012-08-05T15:21:22.773 回答
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
}

或者你应该使用“双叉技巧”将孩子与父母分离,这样孩子就不会像僵尸一样等待父母恢复其退出状态。

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

于 2012-08-05T15:22:47.437 回答
0

!fork()并且fork() == 0两者的行为方式相同。

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

于 2012-08-05T15:14:33.797 回答
0

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

于 2012-08-05T15:16:23.313 回答
0

子进程和父进程的执行顺序由调度程序决定。它确定处理器执行每个进程的时间和时间。因此,对于相同的程序代码,输出的顺序可能会有所不同。源代码的变化导致输出序列的变化纯属巧合。顺便说一句,你的 printf 应该正好相反:如果 fork() 返回 0,它是子进程,而不是父进程。

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

于 2012-08-05T15:40:05.940 回答