fork()返回0,但子进程getpid()!= 0。为什么呢?

时间:2017-09-22 16:00:44

标签: c process fork wait pid

这是测试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 时,它在子进程中。但是孩子的过程显示我是pid 25111 的孩子。我以为子进程pid应为0,为什么它变为25111?

与父进程相同, fork返回25111 ,但getpid()返回25110(我是pid 25110的父亲,等待孩子)

2 个答案:

答案 0 :(得分:5)

  

子进程显示我是pid 25111的孩子。我认为子进程pid应为0

没有。在父fork()中返回孩子的pid。在孩子中,fork返回0 - 任何东西的pid,它只是一个标记。正如getpid告诉你的那样,孩子的pid是25111。

  

使用父进程,fork返回25111,但getpid()返回25110

右。正如getpid告诉你的那样,父pid始终是25110。并且fork()返回了新孩子的pid。

fork返回与父项中返回的getpid相同的值,证明这一切都正常。

听起来您认为fork()总是会返回您所处的流程的pid。但这不会有意义 - 我们已经有getpid调用这一点。

如果您是父母,fork()会返回其他进程的pid,即子级。如果您是孩子,fork()根本不会返回一个pid。 (如果您是孩子,并且您想知道父母的pid,那就是一个好的,频繁的,单独的问题。答案:致电getppid()。)

我们可以总结如下:

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

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

如果fork总是返回一个pid,那么在fork调用之后,查看其返回值,您将无法知道您是父母还是孩子 - 但这是通常是你需要知道的第一件也是最重要的事情。

(在所有这些中,我忽略了第三种可能性,即fork失败,并在父母中返回-1,并且不会在孩子中返回任何内容,因为没有& #39; t one。)

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

答案 1 :(得分:2)

fork返回0并不意味着您的pid为0.它只是返回值fork用于告诉您您是子进程。事实上,fork 从不返回您的pid;它会返回:

  • 你孩子的pid,
  • 0,意思是你是孩子,或
  • -1,表示发生了错误(并且未创建子进程)