[英]I don't understand this example of fork()
我有這個代碼示例,但我不明白為什么這個代碼創建了5個進程加上原始代碼。 (共6個過程)
#include <unistd.h>
int main(void) {
int i;
for (i = 0; i < 3; i++) {
if (fork() && (i == 1)) {
break;
}
}
}
fork()
將進程拆分為兩個,並返回0(如果此進程是子進程),或者返回子進程的PID(如果此進程是父進程)。 所以,這一行:
if (fork() && (i == 1)) break;
說“如果這是父進程,這是第二次通過循環,突破循環”。 這意味着循環運行如下:
i == 0
:第一次通過循環, i
是0,我們創建兩個進程,都進入i == 1
的循環。 現在共有兩個流程
i == 1
:這兩個進程都是fork,但是由於if (fork() && (i == 1)) break;
,它們中的兩個不會繼續迭代if (fork() && (i == 1)) break;
line(兩個不繼續的是fork調用中的父項)。 現在共有四個流程,但其中只有兩個流程繼續循環。
i == 2
:現在,繼續循環的兩個都是fork, 導致6個進程。
i == 3
:所有6個進程都退出循環(因為i < 3 == false
,沒有更多的循環)
如果你的主進程有pid A,而B-F是subprocesses pids,那么:
A spawns B i=0
A spawns C i=1
C run from 'fork' i=1
C spawns D i=2
B run from 'fork' i=0
B spawns E i=1
D run from 'fork' i=2
E run from 'fork' i=1
E spawns F i=2
F run from 'fork' i=2
其中i
是(子)過程'上下文的i
的值。 由於fork
創建了正在運行的進程的精確副本,因此也將復制變量i
。 當A產生B時, i
是0.當A產生C時, i
是1。 進程A現在退出for循環,因為i == 1。
現在,子進程C開始運行, i
== 1.請注意,它不會在for循環中中斷,因為在C的產生點,fork()返回0.而是它將循環,將i
增加到2,生成D ,並因for循環的條件退出。
子進程B啟動時i
== 0。 它產生子進程E,並在for循環內部中斷。 (i == 1)
等等...
如果你想找出這樣的東西,我可以給你一個建議:
制作中間變量並打印出來。
我修改了你的代碼,以便打印出我剛才描述的內容:
#include <unistd.h>
#include <stdio.h>
int main(void) {
int i;
for (i= 0; i < 3; ++i) {
int f = fork();
printf("%i\tspawns\t%i\ti=%i\n", getpid(), f, i);
if (f && (i == 1))
break;
}
getchar();
}
在父進程中,fork()返回子進程的PID,並在子進程中返回0.考慮到這一點,請查看for循環的每次迭代:(為簡單起見,我們假設PID為原始流程是1)
我可以在這里計算六個進程(X):
i=0 fork()
/ \
i=1 fork() fork()
/ \>0 / \>0
| X break | X break
i=2 fork() fork()
/ \ / \
X X X X
循環從i==0
到i==2
。
在第一次迭代中,原始進程(p0)創建另一個(p1)
在第二次迭代中, p0
和p1
創建一個新進程(p2和p3),並且break(因為i==1
並且fork
向父親返回一個非零值)。
在第三次迭代中, p2
和p3
創建一個新進程(p4和p5)。
所以,最后,你有5個新進程。
首先,我們有一個過程。 考慮循環的迭代:
i = 0
第一個進程調用fork。 現在我們有2個流程。
i = 1
這兩個進程調用fork。 現在我們有4個。
Fork在新創建的進程中返回0:兩個進程將從循環中斷,兩個進程將在循環中繼續。
i = 2
剩下的兩個進程調用fork。 我們獲得了2個新流程(共6個)。
在子進程中,循環繼續迭代。 所以他們也產生了新的流程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.