在 C 中使用 fork() 的打印行为

问题描述 投票:0回答:2

我开始学习 fork,但我不明白为什么会打印 4。更具体地说,我不明白子进程何时完成以及父进程何时退出。

#include <stdio.h>
#include <unistd.h>

int main() {
    int i, status;
    int x =1;
    for ( i = 0; i < 3; i++) {
        int pid = fork();
        x++;
        if (pid > 0) {
            wait(&status);
            x--;
            exit(-1);
        }
    }

    printf ("x = %d\n", x);
    return 0;
}

我尝试了一个图表来更好地理解它

Click here to see the diagram

c linux fork
2个回答
2
投票

你已经创建了一个

fork()
链,其中只有最后一个孩子在
for
循环之后还活着。在每次迭代中,
x
增加如下:

original process
x = 1
  |
fork() --> child1
  |          |
x++        x++ (x==2)
parent     fork() --> child2
waits        |          |
for        x++        x++ (x==3)
child1     child1     fork() --> child3
  |        waits        |          |
  |        for        x++        x++ (x==4)
  |        child2     child2       |
  |          |        waits        |
  |          |        for          |
  |          |        child3       |
  |          |          |          |
  |          |          |          |
  |          |          |        printf ("x = %d\n", x);
  |          |          |        return 0;
  |          |        x--
  |          |        exit
  |        x--
  |        exit
x--
exit 

0
投票

初始进程 (670743) 派生一个子进程 (670744),该子进程随后递增它的

x
副本。父母在最终退出之前(其中一个孩子退出后)减少它的
x
副本并不重要。

在下一次迭代中,第一个孩子现在是具有增量值

x
的副本的父级。它分叉了另一个孩子 (670745)。重复直到最后一个孩子(670746)存在循环并打印
x
.

我按如下方式修改了您的代码以证明这一点(还缩小了

i
的范围并消除了
status
变量,因为您不使用它):

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main() {
    int x = 1;
    for (int i = 0; i < 3; i++) {
        printf("pid=%d, x=%d, i=%d\n", getpid(), x, i);
        int pid = fork();
        x++;
        if (pid > 0) {
            wait(&(int) { 0 });
            x--;
            exit(-1);
        }
    }
    printf("pid=%d, x=%d\n", getpid(), x);
}

这表明它是最后一个打印出来的客户端

x

pid=670743, x=1, i=0
pid=670744, x=2, i=1
pid=670745, x=3, i=2
pid=670746, x=4
© www.soinside.com 2019 - 2024. All rights reserved.