回收子程序的兩種方法
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <sys/wait.h>
void sigchld(int signum){
//version 1.導致問題,若同時有三個子程序同時死亡,會丟失訊號
//int r = wait(0);
//printf("%d process is recycled\n",r);
//version 2.導致問題,wait等不到子程序會阻塞.影響父程序。
/*for(;;){
pid_t pid = wait(0);
if(pid == -1){
if(errno != ECHILD){
perror("wait");
exit(-1);
}
printf("all child process have been recycled\n");
break;
}
printf("%d process is recycled\n",pid);
}*/
//vesion 3解決1,2出現的問題
for(;;){
pid_t pid = waitpid(-1,0,WNOHANG);
if(pid == -1){
if(errno != ECHILD){
perror("waitpid");
exit(-1);
}
printf("all child process have been recycled\n");
break;
}
if(pid){
printf("%d process was recycled\n",pid);
}else{
break;
}
}
//for(;;)回收所有子程序,waitpid防止子程序不結束時候阻塞的情況.
}
int main(){
// signal(SIGCHLD,SIG_IGN);//第一種方法,直接忽略SIGCHLD訊號
signal(SIGCHLD,sigchld);//第二種方法,自己寫處理函式
pid_t pid = 0;
for(int i = 0;i < 3;++i){
pid = fork();
if(pid == -1){
perror("fork");
exit(-1);
}
if(pid == 0){
if(i == 2)
sleep(10);
printf("I am %u child process, I will die\n",getpid());
return 0;
}
}
/*for(;;){
int ret = wait(0);
if(ret == -1){
if(errno != ECHILD){
perror("wait");
exit(-1);
}
printf("All child processes have been reclaimed\n");
return 0;
}
printf("%d child process id recycled\n",ret);
}*/
while(1){
printf("waiting...\n");
sleep(1);
}
}