在unix中使用fork
我正在尝试学习fork并在两个fork()之间碰到&&
。在使用fork()
命令时,&&
和||
如何工作。举例来说,如果我有类似如下─在unix中使用fork
fork();
fork() && fork() || fork();
fork() && fork();
这些行执行后催生的进程数为29或30怎么能够得到这样一个结论?
让我们暂时搁置一会儿,考虑&&
和||
操作员的行为。对这些使用fork(2)
没有什么特别之处(尽管这是不必要的混淆,应该只为教育目的而完成)。
回想一下,这些是短路操作,即只评估必要的操作数。在a || b
中,首先评估a
;如果它具有真实值,则b
未被评估,因为||
的结果已知,否则将评估b
。同样,首先评估a && b
,a
;如果它有一个错误值,b
不会被评估,否则,b
被评估以确定结果。
考虑到这一点,让我们逐步计算进程的数量。这个答案的其余部分假定fork(2)
总是成功的。
第一行
fork();
这条线之后,我们产生了总共1个的过程,和有2个上运行的活动进程。
二线
fork() && fork() || fork();
&&
比||
更高的优先级,所以这相当于:
(fork() && fork()) || fork();
所以,我们有2个进程执行此。对第一个fork()
进行评估并创建一个新过程。它在新进程中返回0,因此该进程中的第二个fork()
将不会被评估。请记住,这会发生两次(我们有2个进程) - 我们现在有4个进程。其中两个,第一个fork(2)
返回0,所以第二个fork()
没有执行,但是,第三个fork(2)
将因为||
语义。在另外两个,fork()
返回非零,所以第二个fork()
将被评估,因为它是&&
的一部分。
所以前两个调用最后一个fork()
(||
右边的那个),再次分叉,为进程池添加2个新进程。我们现在有6个进程。其他2在第二fork()
:再次,2个新进程的创建,提高了处理计数到8
现在的情况是类似的:这两个新流程的家长看到fork()
回报不为零,所以他们不要致电第三个fork()
,因为||
的结果现在已知。这两个孩子看到fork()
返回0,所以他们继续评估该线上的第三个和最后一个fork()
,创建2个更多的进程:我们现在有10个进程。
三线
fork() && fork();
好吧,我们有10个流程,要执行这条线。语义相同:10个进程中的每一个执行第一个fork()
,使进程数量为20个。在20个进程中,其中10个进程(该行中第一个fork()
的所有子进程)将看到fork(2)
返回0 ,所以他们不会移动到第二个fork()
。其他10位 - 父母 - 将会看到fork()
返回非零,因此他们会拨打第二位fork()
来确定&&
的最终结果。一起,它们都创建10个以上过程,提高的进程总数为30。
摘要
最后,我们有30个正在运行的进程(总共29个生成)。您可以通过在最终打印和输出计算行数证实了这一点:
#include <stdio.h>
#include <unistd.h>
int main(void) {
fork();
fork() && fork() || fork();
fork() && fork();
printf("PID = %ld\n", (long) getpid());
return 0;
}
实例运行:
$ ./a.out | wc -l
30
你是一个圣人;-) – shellter
'fork'返回0给孩子。 –
是的,我知道它返回0给孩子和孩子的进程ID本身。所以他们是正常的逻辑运算符。但是,为什么最后没有进程是29或30 – Joker
它不是* 29或30 *。 29生成。 30是进程的总数。原来的过程算作一个,另外29个在执行过程中产生。查看我的答案获取更多详情。 –