900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Linux学习之系统编程篇:利用 SIGCHLD 回收子进程

Linux学习之系统编程篇:利用 SIGCHLD 回收子进程

时间:2019-06-14 14:40:07

相关推荐

Linux学习之系统编程篇:利用 SIGCHLD 回收子进程

子进程死亡会给父进程发送 SIGCHLD 信号!(默认动作:父进程忽略该信号)此时父进程就可以捕捉该信号,利用回调函数使用 waitpid 回收子进程。

#include <stdio.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <sys/wait.h>void catch_sig(int sig) // 参数:是捕捉的信号编号{pid_t pid;while(1){pid = waitpid(-1, NULL, WNOHANG);if(pid <= 0){break;}printf("died child_id=%d\n",pid);} }int main(){// 问题:父进程注册捕捉的时候,子进程已经死亡,这样信号根本捕捉不到// 重要思想:先屏蔽信号,再解除屏蔽// 这样:即使子进程先死,内核产生的信号也会被屏蔽掉,然后再解除屏蔽,信号就可以被顺利捕捉了// 父进程先设置屏蔽信号集,屏蔽SIGCHLD信号sigset_t proc; // 定义自定义信号集sigemptyset(&proc); // 第一步:清空自定义信号集,防止随机数干扰其他信号sigaddset(&proc, SIGCHLD); // 将 sigchld 信号 添加到自定义集合sigprocmask(SIG_BLOCK, &proc, NULL); // 通过 自定义信号集 设置 屏蔽信号集// 创建5个子进程int i = 0;for(i = 0 ;i < 5; i ++){pid_t pid = fork();if(pid == 0){break;}}// 此时,6个进程在运行if(i < 5){// 子进程printf("I am %d child, mypid=%d\n", i+1, getpid());}else if(i == 5){// 父进程逻辑 前期已经将信号屏蔽掉了,此时使用 sigaction 进行捕捉struct sigaction act;act.sa_flags = 0;act.sa_handler = catch_sig;sigemptyset(&act.sa_mask); // 不设置临时屏蔽信号sigaction(SIGCHLD, &act, NULL);// 注意:先注册捕捉,再解除屏蔽,顺序不能反sigprocmask(SIG_UNBLOCK, &proc, NULL);while(1){sleep(1); // 父进程一直存活,使子进程先执行return死亡}}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。