我已经执行了一段代码。它如下所示:
#include<stdio.h>
main() {
int i=0;
fork();
printf("The value of i is:%d\n",++i);
fork();
printf("The value of j is:%d\n",++i);
fork();
wait();
}
我得到了以下输出:
The value of i is:1
The value of j is:2
The value of i is:1
The value of j is:2
The value of j is:2
pckoders@ubuntu:~$ The value of j is:2
有人可以向我解释fork()和wait()函数在这里扮演什么角色?
答案 0 :(得分:11)
fork()
来电是字面上的分叉。完成后,您将拥有2个具有精确堆栈的精确进程,并且所有描述符都指向相同的对象。您可以通过返回值区分它们。对于子进程fork()
,返回0,表示父 - 子进程ID。
所以
main() {
int i=0;
fork();
// at this point you are having 2 processes. stdout and stdin are basically just dupplicates.
// (P)
// / \
// (P) (C)
// prints1 prints 1
printf("The value of i is:%d\n",++i); // so 2 processes with print 1
fork();
// now you are having 4 processes( both parent and children forked)
// (P)
// / \
// / \
// (P) (C)
// / \ / \
// (PP) (PC) (CP) (CC)
// prints 2 prints 2 prints 2 prints 2
printf("The value of j is:%d\n",++i);
fork();
// now 4 processes are forking. now you have 8 processes
// (P)
// / \
// / \
// / \
// (P) (C)
// / \ / \
// / \ / \
// (PP) (PC) (CP) (CC)
// / \ / \ / \ / \
// (PPP) (PPC) (PCP) (PCC) (CPP) (CPC) (CCP) (CCC)
wait();
}
答案 1 :(得分:6)
程序生成一个进程树。在每fork
,这棵树分成两部分。如果你拿一张纸,画这棵树并不是很难;唯一困难的是由于您使用前缀i
而使++
值正确。如果您在结束时让每个进程sleep
持续几秒钟,您还可以使用pstree
程序观察树。
然后,每个进程都运行wait
系统调用,waits for any one of its child processes(进程树中的子节点)完成。
答案 2 :(得分:1)
在第一个fork()之后有两个进程(当前和它的精确副本,子进程),它们都打印了1个。
这两个进程中的每一个都与第二个fork()调用重复,并且有4个进程,每个进程打印2个。
它们的输出是随机顺序的,因为它始终与并行执行有关。
答案 3 :(得分:-1)
Forking进程以树状方式创建Children。将每个fork作为二叉树的不同层。当你不发出fork()时,你有一个只有一个根节点的进程树。当你发出问题时一个fork()然后你有一个二元树现在有两个级别,第一个级别将包含父进程,第二个级别将包含两个进程 - 父进程和子进程。
当你想要找出你手边的进程数时,只需继续构建二进制/进程树并查看最后一级有多少个节点,最后一个级别只是进程的当前状态/ tree.Wait函数让你的父进程等待子进程完成执行。在你不想要僵尸进程的应用程序中你需要发出一个等待,否则这些僵尸进程将继续占用系统...... link
请记住,当您始终希望父级在子级之后完成时,等待也很有用。分叉并不总是给出相同的输出,顺序是混乱的,因此总是得到相同的输出,使用wait()。要等待特定的子进程,请使用wait(pid),其中pid是特定子进程的pid,并且可以通过子进程空间内的getpid获取该pid。