之前在學習回收子進程的時候,關於“回收指定子進程”一直拎不清,今日終於頓悟,寫此博客,記錄之。
之前錯誤代碼,在循環創建的五個子進程中,指定回收第三個:
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,就算子進程先死亡,父進程也能訪問。