这是测试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的父亲,等待孩子)
答案 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。)
答案 1 :(得分:2)
fork
返回0并不意味着您的pid为0.它只是返回值fork
用于告诉您您是子进程。事实上,fork
从不返回您的pid;它会返回: