文档章节

SIGCHLD

o
 osc_fmg49rzg
发布于 2019/03/20 11:04
字数 420
阅读 0
收藏 0

精选30+云产品,助力企业轻松上云!>>>

SIGCHLD的产生条件

  子进程终止时

  子进程接收到SIGSTOP信号停止时

  子进程处在停止态,接受到SIGCONT后唤醒时

 

借助SIGCHLD信号回收子进程

 

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

void sys_err(char *str)
{
    perror(str);
    exit(1);
}
void do_sig_child(int signo)
{
    int status;    pid_t pid;
    while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
        if (WIFEXITED(status))
            printf("child %d exit %d\n", pid, WEXITSTATUS(status));
        else if (WIFSIGNALED(status))
            printf("child %d cancel signal %d\n", pid, WTERMSIG(status));
    }
}
int main(void)
{
    pid_t pid;    int i;
    for (i = 0; i < 10; i++) {
        if ((pid = fork()) == 0)
            break;
        else if (pid < 0)
            sys_err("fork");
    }
    if (pid == 0) {    
        int n = 1;
        while (n--) {
            printf("child ID %d\n", getpid());
            sleep(1);
        }
        return i+1;
    } else if (pid > 0) {

      //这里还应对SIGCHLD进行阻塞  防止父进程SIGCHLD还未注册完成子进程就已经死亡
struct sigaction act; act.sa_handler = do_sig_child; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGCHLD, &act, NULL);   //解除阻塞 while (1) { printf("Parent ID %d\n", getpid()); sleep(1); } } return 0; }

 

上述代码若将do_sig_child(),SIGCHLD信号处理函数改为:

void do_sig_child(int signo)
{
    int status;    pid_t pid;
    if((pid = waitpid(0, &status, WNOHANG)) > 0) {  //将while改为if
        if (WIFEXITED(status))
            printf("child %d exit %d\n", pid, WEXITSTATUS(status));
        else if (WIFSIGNALED(status))
            printf("child %d cancel signal %d\n", pid, WTERMSIG(status));
    }
}

此写法会导致子进程回收不完全,原因:在执行信号处理函数时,多个子进程同时死亡,产生多个SIGCHLD信号。但由于函数正在执行故屏蔽SIGCHLD,但执行完成后未决信号集中只记录一次SIGCHLD信号,故回收一次。子进程回收不完全。

 

上一篇: 可重入函数
下一篇: laravel 更新验证
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
使用system函数时出现No child processes错误

问题: 调用system("cp file1 file2");出现No child processes错误,但是cp命令执行成功了。 在开发环境运行程序没有问题,但是当提交到测试环境后,出现的。 解决办法: 在网上搜索了一下,...

卜星星
2016/02/17
178
0
wait(3) - Linux man page

wait(3) - Linux man page http://linux.die.net/man/3/wait PrologThis manual page is part of the POSIX Programmer's Manual. The Linux implementation of this interface may differ (......

Start-up
2012/04/27
386
0
[apue] 等待子进程的那些事儿

谈到等待子进程,首先想到的就是SIGCHLD信号与wait函数族,本文试图厘清二者的方方面面,以及组合使用时可能不小心掉进去的坑。 1. 首先谈单独使用SIGCHLD的场景。下面是一段典型的代码片段:...

osc_p3rdih8s
04/16
3
0
ICS lab9 TinyShell 的10条建议

0.仔细看pdf,尤其是hint部分。 1.先抄书上的代码,然后再添加书上没有的功能。做到一定程度后,测试已有的功能,要不然不好改正。注意规范输出格式。 2.WNOHANG,这个不用说了。 3.调用del...

apachecn_飞龙
2013/11/23
0
0
android init重启service(进程)

在init进程的main函数中有调用sigchldhandlerinit() 设置SIGCHLD signal。这里设置SIGCHLD的处理函数时,在saflags中有加SANOCLDSTOP flag,这个flag表示只有当子进程终止时父进程才接受这个...

osc_7shyb795
2019/08/25
2
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Cloud开发人员如何解决服务冲突和实例乱窜?(IP实现方案)

点击上方“陶陶技术笔记”关注我 回复“资料”获取作者整理的大量学习资料! 一、背景 在我上一篇文章《Spring Cloud开发人员如何解决服务冲突和实例乱窜?》中提到使用服务的元数据来实现隔...

zlt2000
2019/09/06
0
0
Linux下diff命令用法详解

大家好,我是良许。 我们在平时工作的时候,经常要知道两个文件之间,以及同个文件不同版本之间有何异同点。在 Windows 下,有 beyond compare 这个好用的工具,而在 Linux 下,也有很多很强...

osc_th8jvcw7
11分钟前
0
0
万变不离其宗之UART要点总结

[导读] 单片机开发串口是应用最为广泛的通信接口,也是最为简单的通信接口之一,但是其中的一些要点你是否明了呢?来看看本人对串口的一些总结,当然这个总结并不能面面俱到,只是将个人认为...

osc_kyehmyzk
13分钟前
0
0
kafka的认识、安装与配置

认识Kafka 花费越少的精力在数据移动上,就能越专注于核心业务 --- 《Kafka:The Definitive Guide》 认识 Kafka 之前,先了解一下发布与订阅消息系统:消息的发送者不会直接把消息发送给接收...

osc_wy8nhxhn
14分钟前
0
0
使用pandas进行数据处理——DataFrame篇

  今天是pandas数据处理专题的第二篇文章,我们一起来聊聊pandas当中最重要的数据结构——DataFrame。   上一篇文章当中我们介绍了Series的用法,也提到了Series相当于一个一维的数组,只...

开源仔
14分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部