在C中的fork和waitpid

时间:2016-12-18 18:54:30

标签: c linux fork waitpid

我有这段代码,也许我错过了一些东西:

const int NPROCESSES = 32;   
pid_t pids[128];

for (int i = 0; i < NPROCESSES;i ++) {
   pids[i] = fork();
   if (!pids[i]) {  
       /*... other code ...*/
       exit(0);
   }
}

for (int i = 0; i < NPROCESSES; i++)
    waitpid(pids[i], 0, 0);

程序应启动32个进程并等待所有进程终止。但有时程序会被子僵尸进程阻止。 我哪里错了?

1 个答案:

答案 0 :(得分:4)

使用:

waitpid(pids[i], 0, 0);

您指定父级将收集其子级的确切顺序:它将与创建它们的顺序相同。

因此,如果其中一个孩子出于任何原因阻止或延迟,以及之后创建的其他孩子已经完成(并称为exit()),后者将保持僵尸状态,直到父母首先收获前一个孩子。

因此,例如,如果在循环的第一次迭代中创建的进程需要1分钟才能完成,其余31个进程在1秒内完成,那么您将能够观察到等待其父级获得的31个僵尸进程,谁(父母)将等待先获得一个延迟过程。

要更改此行为,父级可以使用:

waitpid(-1, NULL, 0);

代替。 -1的第一个参数中等于waitpid()的值意味着它将收集来自man 2 waitpid的任何子进程:

  

pid的值可以是:

     

< -1

     

表示等待进程组ID等于的任何子进程   pid的绝对值。

     

<强> -1

     

意味着等待任何子进程。

     

0

     

表示等待进程组ID等于的任何子进程   调用过程的那个。

     

> 0

     

意味着等待进程ID等于其值的子进程   PID。

或者,你可以使用:

wait(NULL);

waitpid(-1, NULL, 0)相同。