eg1:
// waitpid1.c
// 2015-08-26 Lucifer Zhang
// Using the waitpid function to reap zombie children in no
// particular order.
#include "csapp.h"
#define N 2
int main()
{
int status, i;
pid_t pid;
/* Parent creates N children */
for (i = 0; i < N; i++) //line:ecf:waitpid1:for
if ((pid = Fork()) == 0) /* child */ //line:ecf:waitpid1:fork
exit(100+i); //line:ecf:waitpid1:exit
/* Parent reaps N children in no particular order */
while ((pid = waitpid(-1, &status, 0)) > 0) { //line:ecf:waitpid1:waitpid
if (WIFEXITED(status)) //line:ecf:waitpid1:wifexited
printf("child %d terminated normally with exit status=%d\n",
pid, WEXITSTATUS(status)); //line:ecf:waitpid1:wexitstatus
else
printf("child %d terminated abnormally\n", pid);
}
/* The only normal termination is if there are no more children */
if (errno != ECHILD) //line:ecf:waitpid1:errno
unix_error("waitpid error");
exit(0);
}
第15行,父程序建立N個子程序,在第16行,每個子程序以一個唯一的退出狀态退出。在第19行,父程序用waitpid作為while循環的測試條件,等待它所有的子程序終止,因為第一個參數是-1,是以對waitpid的調用會阻塞,知道任意一個子程序終止。在每個子程序終止時,對waitpid的調用會傳回,傳回值為該子程序的非零PID。第20行檢查子程序的退出狀态。如果子程序是正常終止的,在此是以調用exit函數終止的,那麼父程序就提取出退出狀态,把它輸出到stdout上。
當回收了所有的子程序之後,再調用waitpid就傳回-1,并且設定errno為ECHILD。第28行檢查waitpid函數是正常終止的,否則就輸出一個錯誤消息。
測試:

注意,程式不會按照特定的順序回收子程序。子程序回收的順序是這台特定的計算機的屬性。在另一個系統上,甚至在同一個系統上再次執行一次,兩個子程序都可能以相反的順序被回收。上面的測試結果也說明了這一點。這是非确定性的(nondeterministic)行為的一個示例,這種非确定性行為使得對并發進行推理非常困難。
下面這個例子做了簡單的改變,消除了不确定性,按照父程序建立子程序的相同順序來回收這些子程序。
eg2:
// waitpid1.c
// 2015-08-26 Lucifer Zhang
// Using waitpid to reap zombie children in the order they were created.
#include "csapp.h"
#define N 2
int main()
{
int status, i;
pid_t pid;
/* Parent creates N children */
for (i = 0; i < N; i++) //line:ecf:waitpid1:for
if ((pid = Fork()) == 0) /* child */ //line:ecf:waitpid1:fork
exit(100+i); //line:ecf:waitpid1:exit
/* Parent reaps N children in no particular order */
while ((pid = waitpid(-1, &status, 0)) > 0) { //line:ecf:waitpid1:waitpid
if (WIFEXITED(status)) //line:ecf:waitpid1:wifexited
printf("child %d terminated normally with exit status=%d\n",
pid, WEXITSTATUS(status)); //line:ecf:waitpid1:wexitstatus
else
printf("child %d terminated abnormally\n", pid);
}
/* The only normal termination is if there are no more children */
if (errno != ECHILD) //line:ecf:waitpid1:errno
unix_error("waitpid error");
exit(0);
}