我只需要理解这句话:
if (fork() && !fork())
它不应该总是错误的吗?我的意思是,如果我写:
if (a && !a)
它总是假的,所以第一个也应该总是假的,我错了吗?我当然是,但我希望有人能向我解释这件奇怪的事情。
我正在为考试学习 C,我必须解决此代码:
int main(){
if(fork && !fork()){
printf("a\n");
}
else printf("b\n");
}
对 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,它不会调用 second fork()
。这是因为&&
如果发现第一个操作数非零,则评估会短路。感谢丹尼尔指出这一点。
所以我们可以用这个做一个表格:
PID fork()1 fork()2
------------------------------
A >0 >0
B =0 >0
C >0 =0
因此,从图表中,流程 Cif
将被评估为TRUE
重要的是要记住,fork()1
没有回到 C 。它从其父级获得了已评估表达式的副本。
我希望这能解释你的问题。
首先,是一个函数。它可能并不总是返回相同的值。
在这种情况下,fork 是一个创建另一个进程的函数。原始进程得到一个正返回值(子进程的 pid),子进程得到一个返回值 0。
在您的代码中,最终共有三个进程。if 语句将评估其中 1 个为真(下面的过程 C)。
A
|__________B
| |
|__C |
| | |
| | |
shouldn't be always false?
不。
因为它不是变量,所以每次调用fork()
都会创建一个新的子进程。
每次调用都fork()
返回两个值,每个进程一个。因此,对于每一个决定,都有一个采用每条路径的过程。
函数调用返回 0 给子进程,fork()
进程 ID 给父进程。基本上,它的作用是分叉一次。如果进程是父进程,则跳转到下一个块,然后子进程再次分叉。这个进程的父进程跳转到下一个块,这个块中的子进程执行if
语句中的代码。