2016-03-25 28 views
4

我想用用C fork()功能在Linux的多进程工作,这是我的代码:进程的父ID不同于PID的父

p1 = fork(); 

if(p1 != 0){ 
    p2 = fork(); 
} 

printf("My PID is %d\n",getpid()); 
printf("My parent PID is %d\n",getppid()); 

现在让我们假设父进程ID是100,并且两个子进程(P1,P2)ID是101 & 102和init进程PID为0我的期望输出是:

My PID is 100 
My parent PID is 0 

My PID is 101 
My parent PID is 100 

My PID is 102 
My parent PID is 100 

相反,我看到的东西不同,两个子进程具有相同的PPID但第一个进程哈与此不同,它是一个不同的PID。下面是一个示例输出我得到:

My PID is 3383 
My parent PID is 3381 

My PID is 3387 
My parent PID is 1508 

My PID is 3386 
My parent PID is 1508 

我的问题是,不应该将两个子进程的父进程PID是? 希望有人能解释一切如何在这里工作,我在做什么(或思考)错误。

+3

当'printf'完成后添加睡眠时会发生什么? –

+0

@MohitJain它实际上修复它,它是如何发生的?我的意思是一个睡眠''printf'不应该真的改变任何东西,因为进程将被创建和'叉'相同... – argamanza

回答

5

[已从意见中确认]

您的输出与时间有关。如果父进程在子进程完成后完成,则您的输出将按预期进行。

如果父进程在子进程之前完成,则输出可能会令人惊讶(在父进程不再存在之前,父进程ID将不同)。一旦父进程死亡(结束),初始化或其他实现定义的进程(在您的情况下为1508)将成为子进程的新父进程。这样的孩子被称为孤儿进程(es)。

据统一UNIX规范,版本2 exit手册页:

所有现有的子进程和调用进程的僵尸进程的父进程ID将被设置为进程ID实施定义的系统过程。也就是说,这些过程应该由一个特殊的系统过程继承。

为了避免这种情况,请确保父进程在获取父pid时处于活动状态。一种方法是在退出之前在父(或全部)进程中添加一个等待。

+1

有道理,但'1508'仍然是一个奇怪的'init' PID。 – alk

+0

@alk这不是必需的初始化。 init的pid是1.事实上,孤儿的ppid被设置为实现定义的进程ID。 –

+0

“*实现 - 定义*”在什么,操作系统?这里是Linux。我似乎错过了一些东西。 – alk

1

有什么不对你的代码

它只是你的父进程退出之前子进程结束 因此,他们成为孤儿,由init或任何实现定义的流程(1508你的情况)的采用。

try puttin wait();让父母完成所有子进程的执行。