[Linux]关于SIGCHLD
之前我们就学过,关于wait和waitpid来处理僵尸进程,父进程等待子进程结束后自己才退出,这样的方法有俩种方式,一种是父进程死死的等子进程退出,也就是使用阻塞的方式等待子进程退出,另一种方式是通过非阻塞的方式,即轮询的方式,这样父进程就可以不用浪费时间一直在那里等子进程退出,而是可以自己干自己的事,过段时间访问一次看子进程退出没,没退出的话干自己的,退出的话则回收子进程,并且自己也随即退出。那么我们是如何知道子进程是否退出呢。其实在这里,子进程终止后会给父进程发送一个SIGCHLD信号,很多同学会想,也没有见过这个信号呀,是因为这个信号的处理方式操作系统默认为忽略的方式处理的,如果你想要知道那个信号,那就用我们学过的让它的处理方式为用户自定义的处理函数即可啦。下面编写一个代码来验证一下子进程终止确实是会给父进程发送SIGCHLD信号的。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
void myhandler(int sig)
{
printf("my sig is %d
",sig);
}
int main()
{
pid_t id = fork();
signal(SIGCHLD,myhandler);
if(id == 0)//child
{
printf("i am child!pid:%d
",getpid());
sleep(5);
exit(1);
}
else //father
{
while(id = waitpid(id,NULL,0) > 0)
{
printf("wait child success:%d pid:%d
",id,getpid());
}
printf("child is quit!%d
",getpid());
}
return 0;
}
运行结果:
等待子进程5秒之后:(发送了一个信号17)
我们可以看一下这个17号信号是什么:(kill -l命令)
对,就是那个SIGCHLD信号。
我们之前用sigaction来捕捉信号,当然我们也可以使用sigaction来捕捉SIGCHLD信号,在这里对于这个例子来说也叫做父进程等待子进程的异步版本,具体实现如下:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
void myhandler(int sig)
{
printf("my sig is %d
",sig);
}
int main()
{
signal(SIGCHLD,myhandler);
pid_t cid;
if((cid = fork())== 0)//child
{
printf("i am child!pid:%d
",getpid());
sleep(5);
exit(1);
}
else
{
struct sigaction act;
act.sa_handler = myhandler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGCHLD,&act,NULL);
while(1)
{
printf("i am parent,my pid is %d
",getpid());
sleep(1);
}
}
// else //father
// {
// while(id = waitpid(id,NULL,0) > 0)
// {
// printf("wait child success:%d pid:%d
",id,getpid());
// }
// printf("child is quit!%d
",getpid());
// }
return 0;
}
运行结果:
当子进程运行5秒后,sigaction函数捕捉到SIGCHLD信号,也即子进程退出的信号,然后父进程运行。
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇: c++详解【new和delete】
- 下一篇:没有了