fork() returns 0,但是子进程getpid()!=0。为什么?

fork() returns 0, but the child process getpid()!=0. Why?

这是测试 fork() 系统调用的 C 代码:

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<wait.h>

int main(int argc, char *argv[])
{

    printf("I am: %d\n", (int)getpid());

    pid_t pid = fork();

    printf("fork returned: %d\n", (int)pid);

    if (pid < 0)
    {
        perror("fork failed");  
    }

    if (pid==0)
    {
        printf("I am the child with pid %d\n", (int)getpid());
        sleep(5);
        printf("Child exiting...\n");
        exit(0);
    }

    printf("I am the parent with pid %d, waiting for the child\n", (int)getpid());
    wait(NULL);
    printf("Parent ending. \n");

    return 0;
}

终端的输出是:

I am: 25110
fork returned: 25111
I am the parent with pid 25110, waiting for the child
fork returned: 0
I am the child with pid 25111
Child exiting...
Parent ending. 

问题:当fork返回:0时,是在子进程中。但是子进程显示I am the child with pid 25111。我以为子进程pid应该是0,为什么变成了25111?

父进程也是一样,fork返回25111,但是getpid()returns25110(我是pid 25110的父进程,等待子进程)

fork returning 0 并不意味着你的 pid 是 0。它只是 return 值 fork 用来告诉你你是 child 过程。事实上 fork 永远不会 return 是你的 pid;它 return 是:

  • 你的 child,
  • 的 pid
  • 0,表示您是 child,或
  • -1,表示发生错误(没有创建 child 进程)

the child process shows I am the child with pid 25111. I thought the child process pid should be 0

没有。在 parent fork() return 中 child 的 pid。在 child、fork returns 0 中, 不是 任何东西的 pid,它只是一个标记。正如 getpid 告诉您的那样,child pid 是 25111。

with the parent process, fork returned 25111, but getpid() returns 25110

没错。正如 getpid 告诉您的那样,parent pid 始终为 25110。并且 fork() return 编辑了新 child 的 pid。

fork return 在 parent 中编辑的值与 getpid return 在 child 中编辑的值相同这一事实证明这一切都正常工作。

听起来您认为 fork() 总是 return 您所在进程的 pid。但这没有意义——我们已经有了 getpid 呼吁。

如果您是 parent,fork() return 是 other 进程的 pid,则 child .如果你是 child,fork() 根本就不是 return pid。 (如果你是 child 并且你想知道你的 parent 的 pid,这是一个很好的、常见的、单独的问题。答案:调用 getppid()。)

我们可以总结如下:

                 parent   child
                 ------   -----
pid:              25110   25111
fork returns:     25111       0
getpid returns:   25110   25111
getppid returns:  ?????   25110

记住这一点的方法是考虑将要调用的代码 fork():它将要做什么,它需要知道什么。 parent 需要知道它是 parent。 child 需要知道它是 child。 parent 经常需要知道 child 的 pid(并且没有其他获取它的方法)。

如果 fork 总是 returned 一个 pid,那么在 fork 调用之后,查看它的 return 值,你将无法知道你是否是 parent 还是 child -- 但这通常是您需要知道的第一个也是最重要的事情。

(在所有这些中我忽略了第三种可能性,即 fork 失败,并且 parent 中的 returns -1 而 return child 中的任何内容,因为没有。)

另见 Why fork() return 0 in the child process?