英文:
Printing behavior using fork() in C
问题
I started learning about forks, but I don't understand why this prints 4. More specifically I don't understand when the child process will finish and the parent process will exit.
#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;
}
I tried a diagram to understand it better
英文:
I started learning about forks, but I don't understand why this prints 4. More specifically I don't understand when the child process will finish and the parent process will exit.
#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;
}
I tried a diagram to understand it better
答案1
得分: 3
你已经创建了一系列fork()
,在for
循环之后只有最后一个子进程会存活。在每次迭代中,x
增加如下:
原始进程
x = 1
|
fork() --> 子进程1
| |
x++ x++ (x==2)
父进程 fork() --> 子进程2
等待 | |
for x++ x++ (x==3)
子进程1 子进程1 fork() --> 子进程3
| 等待 | |
| for x++ x++ (x==4)
| 子进程2 子进程2 |
| | 等待 |
| | for |
| | 子进程3 |
| | | |
| | | |
| | | printf("x = %d\n", x);
| | | return 0;
| | x--
| | 退出
| x--
| 退出
x--
退出
Hope this helps!
英文:
You've made a chain of fork()
s in which only the last child will be alive after the for
loop. At each iteration, x
is increased as such:
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
答案2
得分: 2
以下是您要的翻译:
初始进程(670743)分叉出一个子进程(670744),随后增加了它自己的x
的副本。无论父进程在最终退出之前(在子进程退出之后)对其x
的副本做了什么都不重要。
在下一次迭代中,第一个子进程现在成为具有x
增量值的父进程(现在为2)。它再次分叉出另一个子进程(670745),进程重复直到最后一个子进程(670746)退出循环并打印出x = 4
。
我将您的代码修改如下以演示这一点(还添加了Linux的缺失头文件,减小了i
的作用域并消除了未使用的status
变量):
#include <stdint.h>
#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=%jd, x=%d, i=%d\n", (intmax_t) getpid(), x, i);
int pid = fork();
x++;
if (pid > 0) {
wait(&(int) { 0 });
x--;
exit(-1);
}
}
printf("pid=%jd, x=%d\n", (intmax_t) 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
英文:
The initial process (670743) forks a child (670744) which subsequently increments it's copy of x
. It doesn't matter what the parent does to it's copy of x
before it eventually exits (after a child exits).
In the next iteration the first child is now the parent with a copy of an increment value of x
(now 2). It forks another child (670745) and the process repeat till last child (670746) exists the loop and prints x = 4
.
I modified your code as follows to demonstrate this (also added the missing headers for Linux, reduced scope of i
and eliminated the unused status
variable):
#include <stdint.h>
#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=%jd, x=%d, i=%d\n", (intmax_t) getpid(), x, i);
int pid = fork();
x++;
if (pid > 0) {
wait(&(int) { 0 });
x--;
exit(-1);
}
}
printf("pid=%jd, x=%d\n", (intmax_t) getpid(), x);
}
which shows it's the last child process that prints out x
:
pid=670743, x=1, i=0
pid=670744, x=2, i=1
pid=670745, x=3, i=2
pid=670746, x=4
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论