【Linux】子进程的异步等待方式
SIGCHLD
当子进程退出时,它会向父进程发送SIGCHLD信号,该信号的默认处理方式为忽略,当父进程以阻塞方式等待时,它不能处理自己的工作。 我们自定义一个捕捉信号的函数myhandler
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/wait.h> #include<stdlib.h> void myhandler(int sig) { printf("得到一个信号 : %d 进程号 : %d ",sig,getpid()); } int main() { signal(SIGCHLD,myhandler); pid_t id = fork(); if(id == 0) { printf("我是子进程,pid : %d ...即将退出... ",getpid()); exit(1); } else if(id > 0) { printf("我是父进程... "); waitpid(id,NULL,0);//以阻塞的方式进行等待 } return 0; }
子进程的异步等待
父进程自定义SIGCHLD信号的处理函数,并采用非阻塞方式等待,当子进程退出时,会向父进程发送信号,父进程会进行回收。
当有多个子进程退出时,会给父进程发该数量个信号,但由于只会记录一次,所以只能回收一次
现在我们让父进程一直回收,并采用异步的方式,可以让父进程继续执行自己的工作
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/wait.h> #include<stdlib.h> void myhandler(int sig) { do { pid_t ret = waitpid(-1,NULL,WNOHANG);//wnohang表示以非阻塞的方式等待,-1表示可以等待任何进程 if(ret > 0) { printf("等待成功 %d!!! ",ret); } else { printf("等待失败 %d!!! ",ret); break; } }while(1); } int main() { signal(SIGCHLD,myhandler); pid_t id = fork(); pid_t rid = fork(); if(id == 0) { printf("我是子进程,pid : %d ...即将退出... ",getpid()); exit(1); } else if(id > 0) { while(1) { printf("我是父进程...正在进行工作... "); sleep(1); } } return 0; }