之前在学习回收子进程的时候,关于“回收指定子进程”一直拎不清,今日终于顿悟,写此博客,记录之。
之前错误代码,在循环创建的五个子进程中,指定回收第三个:
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,就算子进程先死亡,父进程也能访问。