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\n",sig,getpid());
}
int main()
{
signal(SIGCHLD,myhandler);
pid_t id = fork();
if(id == 0)
{
printf("我是子进程,pid : %d ...即将退出...\n",getpid());
exit(1);
}
else if(id > 0)
{
printf("我是父进程...\n");
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!!!\n",ret);
}
else
{
printf("等待失败 %d!!!\n",ret);
break;
}
}while(1);
}
int main()
{
signal(SIGCHLD,myhandler);
pid_t id = fork();
pid_t rid = fork();
if(id == 0)
{
printf("我是子进程,pid : %d ...即将退出...\n",getpid());
exit(1);
}
else if(id > 0)
{
while(1)
{
printf("我是父进程...正在进行工作...\n");
sleep(1);
}
}
return 0;
}