通过分叉创建进程和子进程:无法解释的行为

Process and child creation by forking: unexplainable behaviour

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
for(int i=0;i<3;i++)
{
int cpid=fork();
if(cpid==0)
    printf("I am a child with id %d, and my parent is %d\n",getpid(),getppid());
else
    printf("I am a parent with id %d\n",getpid());
}
}

我正在尝试形成一个进程树。输出为:

I am a parent with id 9494 
I am a parent with id 9494 
I am a child with id 9495, and my parent is 9494
I am a parent with id 9494 
I am a child with id 9496, and my parent is 9494
I am a parent with id 9495 
I am a parent with id 9496 
I am a parent with id 9495 
I am a child with id 9498, and my parent is 9495
I am a parent with id 9498 
I am a child with id 9499, and my parent is 3004
I am a child with id 9497, and my parent is 3004
I am a child with id 9500, and my parent is 3004
I am a child with id 9501, and my parent is 3004

我不知道 ID 为 3004 的进程从哪里进来。这段代码总共创建了多少个进程?最终的流程树是什么?我是初学者。

我会帮助解开过程 3004 的谜团。剩下的应该相当容易自己弄清楚(你可能想将 cpid 添加到第二个 printf() 以帮助那个)。

I am a child with id 9499, and my parent is 3004

这里发生的事情是进程 9499 的原始父进程在 9499 有机会调用 getppid() 之前已经死亡。当进程的父进程死亡时,该进程会 重新成为父进程 。在你的例子中,新父进程的 pid 是 3004。这个进程不是你的程序创建的进程树的一部分(它可能位于整个进程树中它上面的某个地方),所以你看不到 "I am a parent with id"为此。

这里有一些相关阅读:process re-parenting: controlling who is the new parent

试试这段代码。

此代码的输出将向您解释更多内容。一些进程 print 在它们的父进程死后它们各自的 printf 函数。这些进程(orphan process)被其他一些进程采用。这可能是 printf 函数打印特殊 pid 的原因。此外,在创建进程和打印它们各自的 pid 之间存在 race-condition,这可以在下面代码的输出中看到。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
    printf("Main\n");
    for(int i=0;i<3;i++) {
        printf("Loop index - %d and pid is - %d\n", i, getpid());
        int cpid=fork();
        if(cpid==0) 
             printf("I am a child with id %d, and my parent is %d with loop index - %d\n",getpid(),getppid(), i);
        else
              printf("I am a parent with id %d and with loop index - %d\n",getpid(), i);
    }
    printf("Terminated - %d\n", getpid());
    return 0;
 }