我正在跟踪此程序并确定创建了多少进程(假设没有发生错误)。我画了一个图表来可视化过程。在我的图表中,第一个fork()
创建的第一个流程包含1
,并且每个相应的父级都有指向每个子流程的箭头。这看起来是否正确?
代码:
1: child2 = 0;
2: child1 = fork(); // fork 1
3: if (child1 == 0)
4: {
5: child2 = fork(); // fork 2
6: }
7: fork(); // fork 3
8: if (child2 > 0)
9: {
10: fork(); // fork 4
11: }
图表:
0
/|\
/ | \
1 3 4
/ \ \
/ \ \
2 3 4
/ /
/ /
3 4
/
/
4
原理
fork()
命令创建了子1
。fork()
命令仅为2
创建了子1
,因为if(child1 == 0)
,即fork()
返回的唯一进程0到child1
是1
。fork()
命令为3
,0
和1
创建了子2
,因为该语句是由每个进程执行的。 fork()
命令为除4
以外的每个进程创建了子2
,因为每个进程都有一个child2
的副本,该副本从fork()
,2
除外,其中child2
为0。更新
正确的图表是:
0
/ \
/ \
1 3
/|\
/ | \
2 4 3
/ \
/ \
3 4
答案 0 :(得分:3)
应用于您的示例的pstree
命令显示:
bash-+-a.out-+-a.out-+-a.out---a.out
| |-a.out---a.out
| `-a.out
`-a.out
如下所示,每行只有一个进程。
bash-+-a.out-+---------------------
+-a.out-+-------------
| +-a.out-------
| | `-a.out
| |-a.out-------
| | `-a.out
| `-a.out-------
`-a.out---------------
,在分支重新排序后,匹配@Macattack的回答。
请注意,您没有关于上图中过程创建的相对时间的信息;它只是最终结果。
要理解图表,让我们看一下父进程分叉后的树:
int main(void) {
int child1 = fork();
}
结果是:
bash-+-a.out---a.out
^ parent ^child
然后,如果孩子再次分叉,
int main(void) {
int child2 = 0;
int child1 = fork();
if (child1 == 0)
child2 = fork();
}
我们得到:
bash-+-a.out---a.out---a.out
^ parent ^child ^grandchild
但是,如果父母再次吵架孩子没有,
int main(void) {
int child2 = 0;
int child1 = fork();
if (child1 > 0)
child2 = fork();
}
我们得到:
bash-+-a.out-+-a.out <- child1
^ `-a.out <- child2
parent
注意pstree
通过合并相同的兄弟姐妹来压缩输出;您需要使用-c
选项来阻止它,并查看完整的树。
答案 1 :(得分:1)
以下是我的解释,你可以决定它是否与你的匹配,我不会像3
,0
和{{1}那样说“创建的孩子1
” “因为每个人都是一个独立的孩子。
我的代码副本:
2
图表:(家长左,孩子右)
int main(void) {
int child2 = 0;
int child1 = fork(); // fork 1
if (child1 == 0)
{
child2 = fork(); // fork 2
}
fork(); // fork 3
if (child2 > 0)
{
fork(); // fork 4
}
printf("%jd\n", getpid());
}