接上一篇:linux_时序竞态-pause函数-sigsuspend函数-异步I/O-可重入函数-不可重入函数

  今天来分享通过SIGCHLD信号来回收子进程,也介绍一下该信号的一些知识点,开始上菜:

此博主在CSDN发布的文章目录:【我的CSDN目录,作为博主在CSDN上发布的文章类型导读】

目录

  • 1.SIGCHLD的产生条件
  • 2.借助SIGCHLD信号回收子进程
  • 3.子进程结束status处理方式
  • 4.SIGCHLD信号注意问题

1.SIGCHLD的产生条件

  ①子进程终止时;
  ②子进程接收到SIGSTOP信号停止时;
  ③子进程处在停止态,接受到SIGCONT后唤醒时;

2.借助SIGCHLD信号回收子进程

  子进程结束运行,其父进程会收到SIGCHLD信号。该信号的默认处理动作是忽略。可以捕捉该信号,在捕捉函数中完成子进程状态的回收。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>void do_sig_child(int signo)
{int status;    pid_t pid;//waitpid:回收子进程//0 回收和当前调用waitpid一个组的所有子进程while ((pid = waitpid(0, &status, WNOHANG)) > 0) {//为非0,进程正常结束if (WIFEXITED(status)){//获取进程退出状态 (exit的参数)printf("子进程 %d 退出 %d\n", pid, WEXITSTATUS(status));}else if (WIFSIGNALED(status))//为非0,进程异常终止{//取得使进程终止的那个x信号的编号。printf("子进程 %d 取消 信号 %d\n", pid, WTERMSIG(status));}}
}int main(void)
{pid_t pid;    int i;for (i = 0; i < 5; i++) {//创建子进程if ((pid = fork()) == 0){break;}    else if (pid < 0){perror("fork error");exit(1);}}if (pid == 0) {    int n = 1;while (n--) {printf("子进程 ID %d\n", getpid());sleep(1);}return i+1;} else if (pid > 0) {struct sigaction act;act.sa_handler = do_sig_child;sigemptyset(&act.sa_mask);//清零信号集合act.sa_flags = 0;sigaction(SIGCHLD, &act, NULL);//注册SIGCHLD信号捕捉函数while (1) {printf("父进程 ID %d\n", getpid());sleep(1);}}return 0;
}

3.子进程结束status处理方式

waitpid函数:
函数作用:
  作用同wait,但可指定pid进程清理,可以不阻塞。
头文件:
  #include <sys/types.h>
  #include <sys/wait.h>
函数原型:
  pid_t waitpid(pid_t pid, int *status, in options);
函数参数:

pid:>0  回收指定ID的子进程,回收指定子进程时,只要该子进程结束,就可回收,回收时间>=子进程结束时间。-1  回收任意子进程(相当于wait)0   回收和当前调用waitpid一个组的所有子进程<-1 回收指定进程组内的任意子进程    可以和kill命令一起使用,例如:kill -9 -进程组ID
options:0 :表示阻塞状态回收子进程WNOHANG:表示非阻塞状态回收子进程
status:保存进程退出的状态,可看wait函数参数的用法。借助宏函数来进一步判断进程终止的具体原因。宏函数可分为如下三组:1. WIFEXITED(status) 为非0    → 进程正常结束WEXITSTATUS(status) 如上宏为真,使用此宏 → 获取进程退出状态 (exit的参数)2. WIFSIGNALED(status) 为非0 → 进程异常终止WTERMSIG(status) 如上宏为真,使用此宏 → 取得使进程终止的那个信号的编号。*3. WIFSTOPPED(status) 为非0 → 进程处于暂停状态WSTOPSIG(status) 如上宏为真,使用此宏 → 取得使进程暂停的那个信号的编号。WIFCONTINUED(status) 为真 → 进程暂停后已经继续运行

返回值:
  成功:返回清理掉的子进程ID;
  失败:-1(无子进程)
特殊返回值:
  当返回0:参数3为WNOHANG,表示子进程正在运行。

想要了解更多回收子进程的方法,请看这篇文章:
linux_回收子进程(何为孤儿进程、僵尸进程、wait函数、waitpid函数)

4.SIGCHLD信号注意问题

  1.子进程继承了父进程的信号屏蔽字和信号处理动作,但子进程没有继承未决信号集spending。
  2.注意注册信号捕捉函数的位置,应该在fork之前,阻塞SIGCHLD信号。注册完捕捉函数后解除阻塞。

以上就是本次的分享了,希望能对大家有所帮助。

linux_SIGCHLD信号-子进程回收相关推荐

  1. Linux 父进程 子进程 回收,回收 fork() 的子进程

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 使用 fork() 函数派生出多个子进程来并行执行程序的不同代码块,是一种常用的编程泛型.但是,在使用 fork() 函 ...

  2. linux操作系统之子进程回收函数wait和waitpid函数小结

    一个进程在终止时会关闭所有的文件描述符,释放用户空间分配的内存,但是它的PCB还保留着,内核在其中还保留着进程的一些信息:如果正常终止,则保留着退出状态:如果异常终止则保存着导致进程种植的信号. 在父 ...

  3. 我的CSDN 目录,作为博主在CSDN上发布的文章类型导读

    此篇文章介绍我的整个CSDN目录,也就是介绍我在CSDN会发布的博客的目录,如果觉得找不到博主的文章从哪里开始的,请从这篇文章开始: 目录 1.linux模块 1.1.linux笔记-C/C++编码 ...

  4. 利用SIGCHLD信号回收子进程

    子进程执行结束之后,父进程如果不对其进行回收,子进程就会变为僵尸进程. 父进程可以通过调用wait()函数和waitpid()函数去回收子进程. 由于子进程结束时会发送SIGCHLD信号给父进程,不过 ...

  5. swoole的process模块创建和使用子进程

    swoole中为我们提供了一个进程管理模块 Process,替换PHP的 pcntl 扩展,方便我们创建进程,管理进程,和进程间的通信. swoole提供了2种进程间的通信: 1.基于 unix so ...

  6. php进程间通信 yoc_swoole的process模块创建和使用子进程

    swoole中为我们提供了一个进程管理模块 Process,替换PHP的 pcntl 扩展,方便我们创建进程,管理进程,和进程间的通信. swoole提供了2种进程间的通信: 1.基于 unix so ...

  7. php swoole process,PHP swoole的process模块创建和使用子进程操作示例

    本文实例讲述了PHP swoole的process模块创建和使用子进程操作.分享给大家供大家参考,具体如下: swoole中为我们提供了一个进程管理模块 Process,替换PHP的 pcntl 扩展 ...

  8. 网络编程之 信号捕捉器(函数指针与回调函数)

    接着我们的信号说下去      之前博主给大家分享到了信号的概念和初步介绍signal函数的形式后就没有继续往下介绍了,实在是因为时间不够,那个时候博主还要上课,现在博主放假了就好好给大家分享一下如何 ...

  9. Linux信号:SIGCHLD信号和僵尸进程

    1. SIGCHLD信号产生条件: (1)子进程终止: (2)子进程收到SIGSTOP信号被暂停: (3)子进程处于暂停状态,收到SIGCONT信号被唤醒. 2. 捕捉SIGCHLD,避免僵尸进程: ...

最新文章

  1. CentOS 7下源码编译安装新版本内核
  2. 常用于生产部署方式详解 灰度发布 滚动发布 蓝绿发布
  3. 深度学习网络调试技巧
  4. React开发(226):默认方法返回一个新的参数两个括号
  5. 哈希表、冲突处理方法、查找长度
  6. 服务器 自检 修改,检查多台服务器初始密码是否修改的shell脚本
  7. 查看linux服务器dns,Linux中查看和设置DNS服务器
  8. Android ActionBar的Overlay模式如何不遮盖顶部内容的问题
  9. fastdfs安装部署
  10. yui3dialog
  11. 静态代理和动态代理的区别和联系
  12. 计算机里的文件中的桌面不见了,电脑重启桌面文件不见了怎么办
  13. MySQL报错:The server quit without updating PID file 我的解决思路和方法
  14. Docker-docker-compose学习笔记(yaml,实战)
  15. Hadoop文件基础操作命令
  16. 识别不同域名访问不同主页
  17. 信息安全体系建设☞开源入侵检测系统HIDS
  18. HMI-44-【多媒体】开启新篇章
  19. HDU 3713 Double Maze
  20. 视差图转为深度图_纽劢研习社 | 深度图的非深度讲解

热门文章

  1. 安装CAD缺少html,Win10系统安装CAD2007失败缺少.NET组件如何解决
  2. 范围变更管控案例_项目范围管理案例之范围确认案例
  3. IDEA牛逼!900行又臭又长的类重构,几分钟搞定
  4. 计算机组成原理 第四版 总线的主模块 总线的从模块,总线的基本概念
  5. 工作表、工作簿保护密码关闭
  6. 计算机音乐数字乐谱未闻花名,未闻花名简谱(歌词)-演唱-小叶歌曲谱
  7. 09 TypeError: Descriptors cannot not be created directly.
  8. 自定义View实战(一) 汽车速度仪表盘
  9. QT comboBox设置下拉菜单()
  10. CF小组训练赛 Holiday 19