父子进程之SIGCHLD

​ 在用wait和waitpid函数处理僵尸进程时,父进程可以阻塞等待子进程结束,也可以非阻塞的查询是否有子进程结束等待处理。但是,第一种方式父进程阻塞了就不能处理自己的工作了,而第二种父进程在处理自己的工作时还需要时不时的轮询一下,使得程序变得复杂。而在子进程终止时,会给父进程发送SIGCHLD信号,该信号的默认处理是忽略,父进程可以自定义该函数,使得父进程可以专心处理自己的工作不必关心子进程,而在子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>

void sigcb()
{
//使用非阻塞的循环来处理SIGCHLD信号
//因为SIGCHLD信号是不可靠信号,有可能会丢失
//一旦接受到信号就处理到不能处理为止
//!=0代表一直有子程序在退出,所以一直循环,>0返回子进程PID (!=0可能<0,没有子进程)
while(waitpid(-1,NULL,WNOHANG) != 0);//多个子进程可能会同时退出,如果同时退出了那么有些信号就会丢失,使得少处理一个信号
printf("Have a child exit!\n");
}

int main()
{
signal(SIGCHLD,sigcb);
int pid = fork();
if(pid == 0)
{
exit(0);
}
//waitpid(-1,NULL,0); //避免产生僵尸子进程,但是使得父进程中后续的操作不能正常继续
while(1)
{
printf("--------\n");
sleep(1;)
}
return 0;
}
0%