用wait和waitpid函数清理僵尸进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不能处理自己的工作了;采用第二种方式,父进程在处理自己的工作的同时还要记得时不时地轮询一下,程序实现复杂。

其实,子进程在终止时会给父进程发SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程即可。

编写一个程序:父进程fork出子进程,子进程调用exit(2)终止,父进程自定义SIGCHLD信号的处理函数,在其中调用wait获得子进程的退出状态并打印。

#include "./common/head.h"/*功能:*子进程正常死亡(exit),发出SIGCHLD信号;父进程绑定该信号的处理函数,给它收尸。
*///父进程给子进程收尸的处理函数
void sig_child(int signo){int sts;pid_t pid = wait(&sts);if(WIFEXITED(sts)){    //子进程正常死亡printf("proc:%d exit with code %d\n", pid, WEXITSTATUS(sts));}return ;
}int main()
{pid_t pid = fork();if(pid < 0){perror("fork");exit(1);}if(pid){    //父进程printf("child pid = %d\n", pid);//绑定信号处理函数struct sigaction newact, oldact;newact.sa_handler = sigchild;sigemptyset(newact.sa_mask);newact.sa_flags = 0;sigaction(SIGCHLD, &newact, &oldact);//父进程一直在工作int n = 10;while(n--){printf("work~\n");sleep(1);}}else{    //子进程sleep(2);exit(2);}return 0;
}

结果:

事实上,由于UNIX的历史原因,要想不产生僵尸进程还有另外一种办法:父进程调用sigaction将SIGCHLD的处理动作置为SIG_IGN,这样fork出来的子进程在终止时会自动清理掉,不会产生僵尸进程,也不会通知父进程。此方法对于Linux可用,但不保证在其他UNIX系统上都可用。编写程序验证这样做不会产生僵尸进程。

#include "./common/head.h"/*功能:*父进程将SIGCHLD信号的处理函数设置成SIG_IGN,子进程正常死亡(exit),这时子进程会自动清理自己的尸体,不会发送SIGCHLD。
*///父进程给子进程收尸的处理函数
void sig_child(int signo){int sts;pid_t pid = wait(&sts);if(WIFEXITED(sts)){    //子进程正常死亡printf("proc:%d exit with code %d\n", pid, WEXITSTATUS(sts));}return ;
}int main()
{pid_t pid = fork();if(pid < 0){perror("fork");exit(1);}if(pid){    //父进程printf("child pid = %d\n", pid);//绑定信号处理函数struct sigaction newact, oldact;newact.sa_handler = SIG_IGN;    //父进程对SIGCHLD信号处理动作设置成SIG_IGN以后,子进程会自动处理自己的尸体,不会产生僵尸进程,也不会通知父进程。sigemptyset(newact.sa_mask);newact.sa_flags = 0;sigaction(SIGCHLD, &newact, &oldact);//父进程一直在工作int n = 10;while(n--){printf("work~\n");sleep(1);}}else{    //子进程sleep(2);exit(2);}return 0;
}

结果: 

关于SIGCHLD信号相关推荐

  1. linux下的僵尸进程处理SIGCHLD信号【转】

    转自:http://www.cnblogs.com/wuchanming/p/4020463.html 什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打 ...

  2. OS / Linux / SIGCHLD 信号

    一.SIGCHLD 的产生条件 子进程终止时. 子进程接收到 SIGSTOP 信号停止时. 子进程处在停止态,接收到 SIGCONT 后唤醒时. 也就是说:子进程的运行状态发生变化就会发送 SIGCH ...

  3. Linux--信号signal、父子进程、SIGCHLD信号相关命令

    目录 1.概念: 2.信号的存储位置: 3.常见的信号的值以及对应的功能说明: 4.信号的值在系统源码中的定义: 5.响应方式: 6.改变信号的相应方式: (1)设置信号的响应方式: (2)默认:SI ...

  4. linux的SIGCHLD信号

    SIGCHLD信号 SIGCHLD的产生条件 子进程终止时 子进程接收到SIGSTOP信号停止时 子进程处在停止态,接受到SIGCONT后唤醒时 借助SIGCHLD信号回收子进程 #include & ...

  5. Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号

    首先区分一下Linux信号跟进程间通信中的信号量,它们的关系就犹如老婆跟老婆饼一样,没有一毛钱的关系. 信号的概念 信号的概念:信号是进程之间事件异步通知的一种方式,属于软中断.比如:红绿灯是一种信号 ...

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

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

  7. 【Linux】SIGCHLD信号

    文章目录 SIGCHLD信号 SIGCHLD信号 回忆: 为了避免出现僵尸进程,父进程需要使用wait或waitpid函数等待子进程结束,父进程可以阻塞等待子进程结束,也可以非阻塞地查询的是否有子进程 ...

  8. [ Linux ] 可重入函数,volatile 关键字,SIGCHLD信号

    目录 1.可重入函数 2.volatile 2.1从信号角度理解volatile的作用 2.2volatile的作用 3.SIGCHLD信号 3.1SIGCHLD信号的验证 1.可重入函数 在数据结构 ...

  9. Linux | 可重入函数 | volatile | SIGCHLD信号

    文章目录 可重入函数 可重入与线程安全 volatile volatile和const同时修饰变量 SIGCHLD信号 可重入函数 当一个函数可以被两个执行流调用,我们称该函数具有重入特征 如果一个函 ...

  10. Day53 Linux setitimer函数 信号集操作函数 信号捕捉 SIGCHLD信号

    目录 setitimer函数 信号集操作函数 1.信号集设定 2.igprocmask函数 3.sigpending函数 信号捕捉 1.signal函数 2.sigaction函数 SIGCHLD信号 ...

最新文章

  1. php 不可以连接远程mysql数据库
  2. CentOS 初体验十三:yum 安装 tomcat
  3. DevNet网站上线
  4. 在县城投资买一辆出租车,一个月能收入多少钱?
  5. ar面部识别_国内手机厂商AR布局报告
  6. 【Linux】vi编辑器命令
  7. 详述一则数据库死锁故障的分析过程
  8. ARM处理器基本指令大全
  9. 服务器内容推送技术(转)
  10. junit.framework.AssertionFailedError: No tests found in错误解决办法
  11. 深度神经网络 轻量化_正则化对深度神经网络的影响
  12. android qq群加群代码,QQ群一键强制加群API源代码
  13. 用R语言下载任意地区DEM数据
  14. java学习第123天,p750-761(05/23)干得漂亮
  15. 测试硬盘怀道的软件,硬盘坏道检测工具(HDDScan)
  16. 固定成本、可变成本、沉没成本、机会成本
  17. 【oracle19c静默安装RAC】
  18. 题十:二叉搜索树与双向链表
  19. 如何使用CAD软件来修改表格中CAD字体颜色?
  20. 在java中如何做身份证号码校验

热门文章

  1. Path *** is not in cwd ***
  2. A. Johny Likes Numbers(有坑的水题)
  3. 计算摄影学前言(0)
  4. wstring和string到底有啥区别
  5. 文献阅读 | 基于单细胞RNA测序数据的谱系追踪
  6. Android音频开发(6):使用 OpenSL ES API(上)
  7. 2018/09/29渡课
  8. Python3.x---第二篇
  9. I/O流(1) 利用 FileWriter() 方法把数据从内存写出到磁盘中
  10. 综合设计一个OPPE主页--导航栏的设计