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

huangapple go评论57阅读模式
英文:

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

Click here to see the diagram

英文:

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 &lt;stdio.h&gt;
#include &lt;unistd.h&gt;

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

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

I tried a diagram to understand it better

Click here to see the diagram

答案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() --&gt; child1
  |          |
x++        x++ (x==2)
parent     fork() --&gt; child2
waits        |          |
for        x++        x++ (x==3)
child1     child1     fork() --&gt; child3
  |        waits        |          |
  |        for        x++        x++ (x==4)
  |        child2     child2       |
  |          |        waits        |
  |          |        for          |
  |          |        child3       |
  |          |          |          |
  |          |          |          |
  |          |          |        printf (&quot;x = %d\n&quot;, 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 &lt;stdint.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;sys/wait.h&gt;
#include &lt;unistd.h&gt;

int main() {
	int x = 1;
	for (int i = 0; i &lt; 3; i++) {
		printf(&quot;pid=%jd, x=%d, i=%d\n&quot;, (intmax_t) getpid(), x, i);
		int pid = fork();
		x++;
		if (pid &gt; 0) {
			wait(&amp;(int) { 0 });
			x--;
			exit(-1);
		}
	}
	printf(&quot;pid=%jd, x=%d\n&quot;, (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

huangapple
  • 本文由 发表于 2023年5月14日 15:05:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76246258.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定