我开始学习 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;
}
我尝试了一个图表来更好地理解它
你已经创建了一个
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
初始进程 (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