#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
printf ("%d", getpid() == fork());
return 0;
}
此程序的输出为00
。我不太明白为什么0
被打印两次。我理解在调用fork()
之后,会创建一个子进程。现在两个流程都继续运行该计划的下一行。这是否意味着子进程将运行return 0
?我可以看到,如果它是00
,我将获得fork() == getpid()
。谢谢!
答案 0 :(得分:6)
fork
不会导致子进程跳转到“下一行”。假设操作成功,fork
函数调用将返回两次,每次进程一次。因此,两个进程都执行与getpid
的比较。
此外,C标准没有规定对getpid
的调用是否在调用fork
之前发生(在这种情况下只发生一次)或之后(在这种情况下它发生两次,返回两个不同的值),但结果并不重要,因为所有可能的情况都会导致比较为假:
fork
失败:没有创建新进程并且它向父进程返回-1,这不是有效的进程ID,因此无法比较{{1}返回给父进程的值}}。 getpid
之前或之后getpid
是否发生并不重要,因为在任何一种情况下它都是相同的过程。
fork
成功:它将子进程ID返回给父进程,并向子进程返回零。
子进程ID不能等于父进程ID(因为它们都在同一时间运行),因此,在父进程中,比较将始终为false,并不重要fork
是在getpid
之前还是之后发生,因为在任何一种情况下都是相同的过程。
如果fork
调用发生在getpid
之前,则子项将与父进程ID进行比较;如果它发生在fork
之后,则孩子将零与孩子的进程ID进行比较。零也不是有效的进程ID,因此无论如何比较都是错误的。
fork
是POSIX认为不会失败的极少数系统调用之一,所以我们不必担心这种可能性。
因此,此程序可以打印的唯一内容是getpid
(如果0
失败)或fork
(如果00
成功)。
我强烈建议不要在真实的程序中写这样的东西。具有“异常”控制流行为的操作(如fork
)应始终作为独立语句完成,因为这使程序更易于人类阅读。你可能还没有意识到这有多重要,所以让我给你留下一个练习:重读你三个多月前写的一个程序,并试着记住它的作用和原因。 (如果你没有编程足够长的时间来做这件事,请在可以做的时候记下来做这个练习。)
答案 1 :(得分:5)
当fork()
在父进程和子进程中都返回时,它会在调用fork()
系统调用结束后立即返回。它可能就像这里的情况一样位于行的中间 - 您返回表达式fork()
的值并使用该值继续评估包含它的表达式 - 在这种情况下 - 是一个条件printf
。
fork()
返回父进程中子进程的PID或子进程中的0(或出错时为-1)。
在这种情况下,两个进程都具有条件getpid() == fork()
返回0(false),因为在父进程中,getpid()
与fork()
返回的值不同,因为它是父进程pid(不是孩子的)和孩子 - fork
返回0,这是非法的PID,getpid()
无法返回。
因此00
输出。