目前,我正在基于UNIX的操作系统上做一些练习。我使用fork()系统调用来创建子进程,代码片段如下:
if(!fork())
{
printf("I am parent process.\n");
}
else
printf("I am child process.\n");
此程序首先执行子进程,然后执行父进程。
但是,当我替换if(!fork()) by if(fork()!=0
时,然后执行父块然后执行子块。我的问题是 - 在两种情况下结果应该是相同的还是有一些原因?在此先感谢!!
答案 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)包含一个示例输出和关于操作顺序的简短讨论。