1.当子进程结束时会产生SIGCHLD信号,可以利用信号捕捉函数捕捉此信号,然后调用回调函数,回收子进程的资源,避免产生僵尸进程。
2.代码如下:
/*捕捉子进程的结束信号,并且在父进程中通过进程捕捉函数,调用回调函数,完成子进程的资源回收*/
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <wait.h>
void my_fun(int num)
{
printf("被处理的信号为:%d\n",num);
//wait(NULL);
while(1)
{
int ret = waitpid(-1,NULL,WNOHANG); //非阻塞的方式回收子进程资源
if(ret > 0)
{
printf("child die,pid = %d\n",ret);
}
else if(ret == 0){
break; //还有子进程,结束此次的回调函数
}
else if(ret == -1)
{
break; //没有子进程了
}
}
}
int main()
{
//提前设置好阻塞信号集,阻塞SIGCHLD,避免子进程很快结束,而父进程还没有创建好进程捕捉,产生错误。
sigset_t set; //创建信号集
sigemptyset(&set);
sigaddset(&set,SIGCHLD); //添加信号
sigprocmask(SIG_BLOCK,&set,NULL);
pid_t pid;
for(int i = 0;i < 10 ;i++ )
{
pid = fork(); //循环的创建子进程
if(pid == 0)
{
break;
}
}
if(pid > 0)
{
//父进程
//捕捉子进程结束时的信号SIGCHLD
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = my_fun;
sigemptyset(&act.sa_mask);
sigaction(SIGCHLD,&act,NULL); //捕捉子进程结束时的信号
//捕捉到信号以后,解除信号集的阻塞
sigprocmask(SIG_UNBLOCK,&set,NULL);
while(1)
{
printf("parent process,pid = %d\n",getpid());
sleep(2);
}
}
else if(pid == 0)
{
printf("child process,pid = : %d\n",getpid());
}
return 0;
}
3.运行结果:
4.总结:对系统中的信号进行捕捉以后,可自行设计回调函数完成需要进行的操作。