moh*_*n_m 3 c unix operating-system fork wait
我有一个 C 源代码,如下所示。
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
#include<sys/types.h>
int main(void) {
pid_t process_id;
int status;
if (fork() == 0)
{
if (fork() == 0)
{
printf("A");
} else {
process_id = wait(&status);
printf("B");
}
} else {
if (fork() == 0)
{
printf("C");
exit(0);
}
printf("D");
}
printf("0");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我在终端中执行它时,我在这张图片中出现了一些输出:
我实际上很困惑这些输出是如何生成的。例如, D0A0~$ B0C 是如何生成的。
谁能解释一下这些输出是如何生成的,以及这段代码中 exit(0) 的功能?
一般来说,如果你有这样的代码
if (fork() == 0) {
printf("I'm a child\n");
} else {
printf("I'm a parent\n");
}
printf("This part is common\n");
Run Code Online (Sandbox Code Playgroud)
然后 fork() 结果为零的 if 分支将在子进程中执行,非零分支将在父进程中执行。之后在两个进程中继续执行(仍然是异步的),因此子进程和父进程都将在 if 之后执行代码。我们可以用下图来图形化地表示它,显示将在每个分支中执行的代码:
fork()
/ \
------- parent ---------- ---------- child -----------
| |
| |
printf("I'm a parent\n"); printf("I'm a child\n");
printf("This part is common\n"); printf("This part is common\n");
Run Code Online (Sandbox Code Playgroud)
现在,让我们为您的代码制作相同的图表。在第一个分叉之后,您根据最上面的情况拆分执行,如果:
fork()
/ \
--------- parent --------- ---------- child -------------
| |
| |
if (fork() == 0) if (fork() == 0)
{ {
printf("C"); printf("A");
exit(0); } else {
} process_id = wait(&status);
printf("D"); printf("B");
}
// Common code // Common code
printf("0"); printf("0");
return 0; return 0;
Run Code Online (Sandbox Code Playgroud)
在父子进程中执行下一个分叉后,我们将得到以下树结构:
fork()
/ \
---- parent ------ ------ child ------
| |
fork() fork()
/ \ / \
--- parent --- --- child --- --- parent --- --- child ----
| | | |
| | | |
printf("D"); printf("C"); process_id = wait(&status); printf("A");
exit(0); printf("B");
printf("D");
printf("0"); printf("0"); printf("0"); printf("0");
return 0; return 0; return 0; return 0;
Run Code Online (Sandbox Code Playgroud)
注意 printf("D"); 出现在 parent-parent 和 parent-child 分支中,因为它实际上是这两个分支中if(fork()==0){}.
此时,所有 4 个进程都在异步执行。
父-父进程打印“D”,然后打印“0”然后退出
父子进程打印“C”然后退出
子父进程等待其子进程完成,然后打印“B”,然后打印“0”并退出
子进程打印“A”,然后“0”然后退出
如您所见,这些进程的输出几乎可以任意交错,唯一的保证是在子父进程打印“B0”之前,子子进程将打印“A0”。用于运行程序的 shell 将在主进程(即父-父进程)完成后重新获得控制权。但是,当控制权返回到 shell 时,仍然可能有其他进程在运行,因此在 shell 输出其命令提示符后可能会出现某些进程的输出。例如,以下事件链是可能的:
父-父获得控制权。它打印“D0”并退出,控制权返回给外壳。
子父进程获得控制权。它开始等待(阻塞)子进程。
child-child 进程获得控制权。它打印“A0”并退出。
同时shell进程获得控制权并打印命令提示符“~$”
子父进程获得控制权。由于子进程完成,它被解除阻塞,打印“B0”并退出。
父子进程获得控制权,打印“C”并退出。
组合输出为“D0A0~$B0C”。它解释了您示例中的最后一行。
| 归档时间: |
|
| 查看次数: |
115 次 |
| 最近记录: |