我不明白fork()的这个例子

cle*_*leo 14 c unix fork

我有这个代码示例,但我不明白为什么这个代码创建了5个进程加上原始代码.(共6个过程)

#include <unistd.h>

int main(void) {
    int i;
    for (i = 0; i < 3; i++) {
        if (fork() && (i == 1)) {
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

流程图

Tim*_*nes 30

fork()将进程拆分为两个,并返回0(如果此进程是子进程),或者返回子进程的PID(如果此进程是父进程).所以,这一行:

if (fork() && (i == 1)) break;
Run Code Online (Sandbox Code Playgroud)

说"如果这是父进程,这是第二次通过循环,突破循环".这意味着循环运行如下:

  • i == 0:第一次通过循环, i是0,我们创建两个进程,都进入循环i == 1.现在共有两个流程

  • i == 1:这两个进程都是fork,但是其中两个因为该if (fork() && (i == 1)) break;行而没有继续迭代(两个不继续的都是fork调用中的父进程).现在共有四个进程,但只有两个进程继续循环.

  • i == 2:现在,两个继续循环的两个fork,导致6个进程.

  • i == 3:所有6个进程退出循环(因为i < 3 == false,没有更多的循环)


joc*_*tee 12

如果你的主进程有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
Run Code Online (Sandbox Code Playgroud)

(子)过程'上下文i的价值在哪里i.由于fork创建了正在运行的进程的精确副本,因此i也将复制该变量.当A产生B时,i为0.当A产生C时,i为1.进程A现在退出for循环,因为i == 1.

现在,子进程C开始运行,使用i== 1.注意它不会在for循环内部中断,因为在C的产生点,fork()返回0.而是它将循环,增加到i2,生成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();
}
Run Code Online (Sandbox Code Playgroud)


小智 6

在父进程中,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所以循环完成.


Kar*_*ath 5

我可以在这里计算六个进程(X):

i=0          fork()
            /      \
i=1   fork()        fork()
      /    \>0       /   \>0
      |    X break   |   X break
i=2 fork()       fork()
     / \          /  \
    X  X         X    X
Run Code Online (Sandbox Code Playgroud)