簡體   English   中英

我不明白fork()的這個例子

[英]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)

  1. 我== 0
    • 過程1:i == 0,fork返回子進程的PID(比如2)(2!= 0),true && false == false,所以我們不會中斷。
    • 過程2:i = 0,fork返回0,false && false == false,所以我們不會中斷。
  2. 我== 1
    • 過程1:i == 1,fork返回子進程的PID(比如3),true && true == true,所以break。
    • 過程2:i == 1,fork返回子進程的PID(比如4),true && true == true,所以break。
    • 過程3:i == 1,fork返回0,false && true == false,所以不要中斷。
    • 過程4:i == 1,fork返回0,false && true == false,所以不要中斷。
  3. 我== 2
    • 過程1不在循環中。
    • 過程2不在循環中。
    • 過程3:i == 2,fork返回子進程的PID(比如5),true && false == false,所以不要破壞
    • 過程4:i == 2,fork返回子進程的PID(比如6),true && false == false,所以不要破壞
    • 過程5:i == 2,fork返回0,false && false == false,所以不要中斷
    • 過程6:i == 2,fork返回0,false && false == false,所以不要中斷
  4. 我= = 3所以循環完成。

我可以在這里計算六個進程(X):

i=0          fork()
            /      \
i=1   fork()        fork()
      /    \>0       /   \>0
      |    X break   |   X break
i=2 fork()       fork()
     / \          /  \
    X  X         X    X

循環從i==0i==2

在第一次迭代中,原始進程(p0)創建另一個(p1)

在第二次迭代中, p0p1創建一個新進程(p2和p3),並且break(因為i==1並且fork向父親返回一個非零值)。

在第三次迭代中, p2p3創建一個新進程(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM