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