c 中 fork() 的输出
Output from fork() in c
我最近运行进入了这段代码,并没有完全理解它。
- 什么情况会导致pid == 0?
- 为什么 wait(NULL) 导致程序进入 if(pid == 0)
基本上我没有完全理解下面的输出。任何帮助,将不胜感激。谢谢。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // standard POSIX header file
#include <sys/wait.h> // POSIX header file for 'wait' function
int main(void)
{
int i = -1;
int pid;
pid = getpid();
fprintf(stdout, "parent pid = %d\n", pid);
pid = fork();
if (pid == 0)
{
for (i = 0; i < 10; ++i)
{
fprintf(stdout, "child process: %d\n", i);
sleep(1);
}
exit(0);
}
else
{
fprintf(stdout, "child pid = %d\n", pid);
fprintf(stdout, "waiting for child\n");
wait(NULL);
fprintf(stdout, "child terminated\n");
}
fprintf(stdout, "parent terminating\n");
return 0;
}
输出:
parent pid = 2896
child pid = 5840
waiting for child
child process: 0
child process: 1
child process: 2
child process: 3
child process: 4
child process: 5
child process: 6
child process: 7
child process: 8
child process: 9
child terminated
parent terminating
正如 and 评论中提到的,简单回答你的第一个问题:
0
是fork()
调用成功返回后child进程内部的返回值。 child 进程的执行从 if (pid == 0)
块开始。它遍历 for
循环,每次迭代 prints
和 sleeps
,然后最后 exit(0)
被调用,并且 child 过程终止。
parent 进程 在 fork()
调用之后的执行在 else
块中继续。 parent过程中返回的PID是child的PID ].
简单回答你的第二个问题:
wait(NULL
)用于等待child进程的状态变化。在这种特定情况下,状态更改是 child 的终止。参数 NULL
只是表示不会存储任何状态信息。
有关更多详细信息,请阅读链接的手册页。
fork(2)
系统调用创建了第二个 child 进程,因此,该调用在 parent 中被调用一次,但是 returns,parent 和 child.
因此,调用后的代码需要一些指示才能知道我们是在 parent 还是 child 中执行代码,因为这允许 parent 和 child 从现在开始从通用代码转移。
fork(2)
的定义,在手册页中是这样写的:
- 到 return
-1
并将 errno
设置为指示 fork(2)
调用失败原因的值。
- 到 return
0
child 子进程。
- 到return
pid_t
child进程id到parent进程(一个正数)所以它可以知道刚刚启动的新子进程的pid。
wait(NULL);
不在if (pid == 0)
,而是在else
部分,所以确实在if (pid != 0)
或者在parent 进程。 parent 进程必须知道 child 是否已完成以及如何完成,并且必须与其同步,原因如下:
child可以在parent之前exit(2)
,但是根据child的工作量,它可以在parent之后做parent 结束。如果 parent 在 child 之前结束,您将再次收到 shell 提示,并且您的屏幕会因 child 的输出而变得模糊,紧接在 child 之后已发出提示。这不是您通常想要的,因此 parent 中的 wait(2)
调用只是礼貌,因此 shell 仅在所有操作完成后提示您。
一个好的测试是在你的示例中评论 wait(2)
调用,看看会发生什么。
wait(2)
系统调用是一种了解您的 child 是如何结束它的 运行 的方法(主要是如果您 exec(2)
中的某个其他程序child 的过程)你可以了解你的 child 是否因为它 exit(2)
ed(并收到它的退出代码)而死,因为它被中断了(以及它收到的信号是什么)或者如果由于某种原因它已被 user/system 停止。
阅读 fork(2)
、exec(2)
、exit(2)
和 wait(2)
系统调用(全部作为一组相关调用)将启发所有进程关系以及如何所有这些系统调用协作管理 unix 进程系统。
我最近运行进入了这段代码,并没有完全理解它。
- 什么情况会导致pid == 0?
- 为什么 wait(NULL) 导致程序进入 if(pid == 0)
基本上我没有完全理解下面的输出。任何帮助,将不胜感激。谢谢。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // standard POSIX header file
#include <sys/wait.h> // POSIX header file for 'wait' function
int main(void)
{
int i = -1;
int pid;
pid = getpid();
fprintf(stdout, "parent pid = %d\n", pid);
pid = fork();
if (pid == 0)
{
for (i = 0; i < 10; ++i)
{
fprintf(stdout, "child process: %d\n", i);
sleep(1);
}
exit(0);
}
else
{
fprintf(stdout, "child pid = %d\n", pid);
fprintf(stdout, "waiting for child\n");
wait(NULL);
fprintf(stdout, "child terminated\n");
}
fprintf(stdout, "parent terminating\n");
return 0;
}
输出:
parent pid = 2896
child pid = 5840
waiting for child
child process: 0
child process: 1
child process: 2
child process: 3
child process: 4
child process: 5
child process: 6
child process: 7
child process: 8
child process: 9
child terminated
parent terminating
正如
0
是fork()
调用成功返回后child进程内部的返回值。 child 进程的执行从 if (pid == 0)
块开始。它遍历 for
循环,每次迭代 prints
和 sleeps
,然后最后 exit(0)
被调用,并且 child 过程终止。
parent 进程 在 fork()
调用之后的执行在 else
块中继续。 parent过程中返回的PID是child的PID ].
简单回答你的第二个问题:
wait(NULL
)用于等待child进程的状态变化。在这种特定情况下,状态更改是 child 的终止。参数 NULL
只是表示不会存储任何状态信息。
有关更多详细信息,请阅读链接的手册页。
fork(2)
系统调用创建了第二个 child 进程,因此,该调用在 parent 中被调用一次,但是 returns,parent 和 child.因此,调用后的代码需要一些指示才能知道我们是在 parent 还是 child 中执行代码,因为这允许 parent 和 child 从现在开始从通用代码转移。
fork(2)
的定义,在手册页中是这样写的:- 到 return
-1
并将errno
设置为指示fork(2)
调用失败原因的值。 - 到 return
0
child 子进程。 - 到return
pid_t
child进程id到parent进程(一个正数)所以它可以知道刚刚启动的新子进程的pid。
- 到 return
wait(NULL);
不在if (pid == 0)
,而是在else
部分,所以确实在if (pid != 0)
或者在parent 进程。 parent 进程必须知道 child 是否已完成以及如何完成,并且必须与其同步,原因如下:child可以在parent之前
exit(2)
,但是根据child的工作量,它可以在parent之后做parent 结束。如果 parent 在 child 之前结束,您将再次收到 shell 提示,并且您的屏幕会因 child 的输出而变得模糊,紧接在 child 之后已发出提示。这不是您通常想要的,因此 parent 中的wait(2)
调用只是礼貌,因此 shell 仅在所有操作完成后提示您。一个好的测试是在你的示例中评论
wait(2)
调用,看看会发生什么。wait(2)
系统调用是一种了解您的 child 是如何结束它的 运行 的方法(主要是如果您exec(2)
中的某个其他程序child 的过程)你可以了解你的 child 是否因为它exit(2)
ed(并收到它的退出代码)而死,因为它被中断了(以及它收到的信号是什么)或者如果由于某种原因它已被 user/system 停止。
阅读 fork(2)
、exec(2)
、exit(2)
和 wait(2)
系统调用(全部作为一组相关调用)将启发所有进程关系以及如何所有这些系统调用协作管理 unix 进程系统。