1

考虑以下指令:

for(int i = 0; i < 3; i++)
    fork();

我试图弄清楚创建过程的数量和图形创建的步骤。

所以上面的代码等价于:

fork();
fork();
fork();

这张图说明了这个问题的官方答案:

图形

我无法想象这个图表是如何创建的。

这就是我绘制图表的方式。

  1. 因此,第一个 fork 将创建父进程 (p1) 的子副本 (p2)。我们有2个过程。

  2. 第二个分叉将通过创建子进程(p3 和 p4)来复制 p1 和 p2 父级。

  3. 第三次分叉,将复制 p1、p2、p3 和 p4,通过创建子进程(p5、p6、p7、p8)

如何获得与老师相同的图表?

4

2 回答 2

6

如果您想要一个类似于官方答案的图表,请尝试停止思考事情是如何并发运行的,而是专注于进程的世代(父母、孩子、孙辈等)。

一开始,只有一个进程p0,要进行三个分叉。当做这三个叉子时,它创建p1了两个叉子走,p2一个叉子走p3,没有叉子。然后p0退出(仅p1,p2p3保持)。

我们可以扔掉,p3因为它没有叉子,只剩下p1p2)。

然后进程p1执行它的第二个分叉生产p4,只剩下一个分叉,然后执行第三个分叉制造p5,没有剩下一个分叉。p1现在完成并退出(p2p4p5保持)。

类似于p3,p5可以被扔掉,因为它没有叉子了。这留下p2p4

同样,p2只剩下一个叉子,所以它创建p6时没有叉子。然后由于没有叉子p2p6退出,离开p4

进程p4只剩下一个叉子,因此它创建p7时没有叉子,然后它们都退出了。

通过基于父系而不是进程开始时间绘制具有深度的图表(尽管开始时间(a)控制进程在特定深度水平存在的位置,例如,请参见p1和),您的图表应该与给定的图表匹配p2p3

所以这样想:

  Sequence within generation -------->
G
e           ______p00______
n          /       |       \
e       p01       p02       p03
r      /   \       |
a   p04     p05   p06
t    |
i   p07
o
n
|
V

(a)请记住,这里定义的开始时间是进程开始存在的时间——进程执行实际有用工作的顺序也取决于调度的变幻莫测。

于 2012-06-13T04:03:15.963 回答
1

如果我们从 P0 开始,它将生成进程 P1、P2 和 P3,但每个进程将有不同的 i,因为在 fork 时我们已经复制了堆栈上的所有值。

生成 P1 i = 0
生成 P2 i = 1
生成 P3 i = 2
i = 3 不再 < 3

P1
生成 P4 i = 1,生成 P4 时 i 设置为 1,因为它是 fork i 递增,之前为 0 .
生成 P5 i = 2,
i 不再 < 3

P2
生成 P6 i = 2,再次生成 P6 时 i 为 2,因为在调用 fork 时它为 1。
i 不再 < 3

P3
i 不再 < 3

P4
生成 P7 i = 2
i 不再 < 3

好吧,你明白了....

于 2012-06-13T04:14:57.697 回答