4

我只需要理解这句话:

if (fork() && !fork())

它不应该总是错误的吗?我的意思是,如果我写:

if (a && !a)

它总是假的,所以第一个也应该总是假的,我错了吗?我当然是,但我希望有人能向我解释这件奇怪的事情。

我正在为考试学习 C,我必须解决此代码:

int main(){
if(fork && !fork()){
   printf("a\n");
}
else printf("b\n");
}
4

5 回答 5

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,它不会调用 second fork()这是因为&&如果发现第一个操作数非零,则评估会短路。感谢丹尼尔指出这一点。

所以我们可以用这个做一个表格:

PID       fork()1      fork()2
------------------------------
A           >0          >0
B           =0          >0
C           >0          =0

因此,从图表中,流程 Cif将被评估为TRUE

重要的是要记住,fork()1没有回到 C 。它从其父级获得了已评估表达式的副本。

我希望这能解释你的问题。

于 2012-07-10T20:24:22.967 回答
6

首先,是一个函数。它可能并不总是返回相同的值。

在这种情况下,fork 是一个创建另一个进程的函数。原始进程得到一个正返回值(子进程的 pid),子进程得到一个返回值 0。

在您的代码中,最终共有三个进程。if 语句将评估其中 1 个为真(下面的过程 C)。

     A
     |__________B
     |          |
     |__C       |
     |  |       |       
     |  |       |        
于 2012-07-10T20:05:06.097 回答
3
shouldn't be always false?

不。

因为它不是变量,所以每次调用fork()都会创建一个新的子进程。

于 2012-07-10T20:00:21.847 回答
1

每次调用都fork()返回两个值,每个进程一个。因此,对于每一个决定,都有一个采用每条路径的过程。

于 2012-07-10T20:02:40.340 回答
0

函数调用返回 0 给子进程,fork()进程 ID 给父进程。基本上,它的作用是分叉一次。如果进程是父进程,则跳转到下一个块,然后子进程再次分叉。这个进程的父进程跳转到下一个块,这个块中的子进程执行if语句中的代码。

于 2012-07-10T20:07:38.303 回答