我只需要理解这句话:
if (fork() && !fork())
不应该总是假的吗?我的意思是,如果我写:
if (a && !a)
总是假的,所以第一个也应该总是假的,我错了吗?我当然是,但我希望有人可以向我解释这个奇怪的事情。
我正在攻读C考试,我必须解决这个问题:
int main(){
if(fork && !fork()){
printf("a\n");
}
else printf("b\n");
}
答案 0 :(得分:8)
每次调用unix进程创建系统调用fork()都会返回两次。首先,它将子节点的PID返回给父节点(调用fork()的进程)。第二,它返回0给新创建的孩子。
来自手册页:
返回值
成功时,父进程返回子进程的PID,并在子进程中返回0。失败时,在父项中返回-1,不创建子进程,并正确设置errno。
在你的情况下
if (fork() && !fork())
if
内的语句,调用fork两次。那么接下来会发生什么:
A
|----------------B
| |
|---C |
| | |
现在,对fork()
的第一次调用将在A和B中返回。在A中它将为非零,在B中将为零。
对fork()的第二次调用只会从A中引发,因为第一个fork将0返回给B,它不会唤醒第二个fork()
。 因为如果发现第一个操作数非零,&&
会使评估短路。感谢Daniel指出这一点。
所以我们可以制作一个表格:
PID fork()1 fork()2
------------------------------
A >0 >0
B =0 >0
C >0 =0
因此,从图表中,流程C的if
将评估为 TRUE
重要的是要记住,fork()1
没有回到C。它从其父级获得了已经评估的表达式的副本。
我希望这能解释你的问题。
答案 1 :(得分:6)
首先,是一个功能。它可能并不总是返回相同的值。
在这种情况下,fork是一个创建另一个进程的函数。原始进程获得(孩子的pid)的正返回值,子进程的返回值为0.
在您的代码中,最终总共有三个进程。对于其中一个,if语句将评估为true(下面的过程C)。
A
|__________B
| |
|__C |
| | |
| | |
答案 2 :(得分:3)
shouldn't be always false?
没有。
因为它不是变量,所以每次调用fork()
都会创建一个新的子进程。
答案 3 :(得分:1)
每次调用fork()
都会返回两个值,每个进程一个。因此,对于每个决策,都有一个流程采用每条路径。
答案 4 :(得分:0)
fork()
函数调用向子进程返回0,向父进程返回进程ID。基本上,它的作用就是一次。如果进程是父进程,则跳转到下一个块,然后子进程再次分叉。此进程的父级跳转到下一个块,此块中的子级执行if
语句中的代码。