c 中 fork() 的输出

Output from fork() in c

我最近运行进入了这段代码,并没有完全理解它。

  1. 什么情况会导致pid == 0?
  2. 为什么 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 评论中提到的,简单回答你的第一个问题:

0fork()调用成功返回后child进程内部的返回值。 child 进程的执行从 if (pid == 0) 块开始。它遍历 for 循环,每次迭代 printssleeps,然后最后 exit(0) 被调用,并且 child 过程终止。

parent 进程fork() 调用之后的执行在 else 块中继续。 parent过程中返回的PID是child的PID ].

简单回答你的第二个问题:

wait(NULL)用于等待child进程的状态变化。在这种特定情况下,状态更改是 child 的终止。参数 NULL 只是表示不会存储任何状态信息。

有关更多详细信息,请阅读链接的手册页。

  1. 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。
  2. 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 进程系统。