之前在学习回收子进程的时候,关于“回收指定子进程”一直拎不清,今日终于顿悟,写此博客,记录之。

之前错误代码,在循环创建的五个子进程中,指定回收第三个:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<unistd.h>
 4 #include<sys/wait.h>
 5 int main()
 6 {
 7    pid_t pid,w_pid;
 8    int i;
 9     //循环创建5个进程
10    for(i=0;i<5;i++)
11   {
12      if(fork()==0)
13      {
14         if(i==2)
15             pid=getpid();  //记录第三个进程的pid
16         break;
17      }
18   }  
19    //父进程
20    if(i==5)
21    {
22       w_pid=waitpid(pid,NULL,0);  //阻塞回收指定第三个子进程,
23       if(w_pid==-1)
24      {
25         perror("waitpid error\n");
26         exit(1);
27      }  
28       printf("回收的子进程的PID=%d\n,"w_pid);
29    }
30     else
31     {   //各个子进程睡几秒然后go die
32          sleep(i);
printf("i am child pid=%d\n",getpid());
33 } 34 }

错误分析:   

  从打印结果来看,回收的子进程并不是第三个进程,而是第一个进程,这个因为在第15行,是在子进程中保存了父进程要使用的变量pid,而子进程先于父进程死亡,那么子进程用户空间会消失,自然用户空间中的变量也会消失,所以父进程再操作这个变量就不会得到我们所期望的值。

 

改正过后的代码

 1 pid_t pid ,tmpid,wpid;
 2 for(i=0;i<5;i++)
 3 {
 4     pid=fork();
 5     //子进程
 6     if(pid==0)
 7         break;
 8     //父进程
 9     if(i==2)
10         tmpid =pid; 
11 }
12 //父进程
13 if(i==5)
14 {
15     wpid=waitpid(tmpid,NULL,0);
16     if(wpid==-1)
17     {
18         perror("waitpid error\n");
19         exit(1);
20     }
21     printf("wpid=%d\n",wpid);
22 }
23 //子进程
24 else
25 {
26     sleep(i);
27 }
28              

  在第10行中,也就是在父进程中保存了变量tmpid,就算子进程先死亡,父进程也能访问。