SIGCHLD的产生条件

子进程终止时

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

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

借助SIGCHLD信号回收子进程

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

/***
sigchild.c
***/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h> void sys_err(char *str)
{
perror(str);
exit();
}
void do_sig_child(int signo)
{
int status; pid_t pid;
while ((pid = waitpid(, &status, WNOHANG)) > ) {
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 = ; i < ; i++) {
if ((pid = fork()) == )
break;
else if (pid < )
sys_err("fork");
}
if (pid == ) {
int n = ;
while (n--) {
printf("child ID %d\n", getpid());
sleep();
}
return i+;
} else if (pid > ) {
struct sigaction act;
act.sa_handler = do_sig_child;
sigemptyset(&act.sa_mask);
act.sa_flags = ;
sigaction(SIGCHLD, &act, NULL); while () {
printf("Parent ID %d\n", getpid());
sleep();
}
}
return ;
}
/***
my_sigchild.c
***/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<signal.h> void sys_err(char *str)
{
perror(str);
exit();
} void do_sig_child(int signo)
{
int status;
pid_t pid; while( (pid = waitpid(,&status,WNOHANG)) > )
{
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()
{
pid_t pid;
int i; for(i = ; i < ; i++)
{
if((pid = fork()) == )
{
break;
}
else if(pid < )
{
sys_err("fork");
}
} if( == pid)
{
int n = ;
while(n--)
{
printf("child ID %d\n",getpid());
sleep();
}
return i+;
}
else if(pid > )
{
struct sigaction act;
act.sa_handler = do_sig_child;
sigemptyset(&act.sa_mask); while()
{
printf("Parent ID %d\n",getpid());
sleep();
} }
return ;
}

分析该例子。结合 17)SIGCHLD 信号默认动作,掌握父使用捕捉函数回收子进程的方式。              【sigchild.c】

如果每创建一个子进程后不使用sleep可以吗?可不可以将程序中,捕捉函数内部的while替换为if?为什么?

if ((pid = waitpid(0, &status, WNOHANG)) > 0) { ... }

思考:信号不支持排队,当正在执行SIGCHLD捕捉函数时,再过来一个或多个SIGCHLD信号怎么办?

SIGCHLD函数的更多相关文章

  1. Linux下的进程环境

    僵尸进程.孤儿进程.守护进程.进程组.会话.前台进程组.后台进程组 1,僵尸进程 子进程结束,父进程没有明确的答复操作系统内核:已收到子进程结束的消息.此时操作系统内核会一直保存该子进程的部分PCB信 ...

  2. 三十一、Linux 进程与信号——SIGCHLD 信号、kill和raise函数以及alarm函数

    31.1 SIGCHLD 信号 子进程状态发生变化(子进程结束)产生该信号,父进程需要使用 wait 调用来等待子进程结束并回收它. 避免僵尸进程 #include <stdio.h> # ...

  3. SIGCHLD和wait/waipid函数的关系

    SIGCHILD只是在子进程退出的时候发送给父进程的一个信号值,这是一种异步通知父进程的方式.父进程可以捕获,忽略这个信号,默认动作是忽略此信号. 常用的使用方式是,当SIGCHILD信号发生时候,主 ...

  4. 调用wait的SIGCHLD信号处理函数

    #include <stdio.h> #include <sys/wait.h> void sig_chld(int signo) { pid_t pid; int stat; ...

  5. 调用waitpid的SIGCHLD信号处理函数

    #include <stdio.h> #include <sys/wait.h> void sig_chld(int signo) { pid_t pid; int stat; ...

  6. Linux C--信号 sigaction函数

    使用 sigaction 函数: signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到了一定的限制.而 POSIX 标准定义的信号处 ...

  7. 关于linux下system()函数的总结

    导读 曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入.这里必须要搞懂system()函数,因为有时你不得不面对它. 先来看一下system()函数的简单 ...

  8. unp TCP 客户端服务器回射程序中对SIGCHLD信号的处理

    第五章中,有一个例子模拟客户端并发的终止TCP连接,服务器捕捉并处理SIGCHLD信号并调用waitpid函数防止僵死进程的出现.信号处理函数中核心的一句是: , &statloc, WNOH ...

  9. Linux 信号详解一(signal函数)

    信号列表 SIGABRT 进程停止运行 SIGALRM 警告钟 SIGFPE 算述运算例外 SIGHUP 系统挂断 SIGILL 非法指令 SIGINT 终端中断 SIGKILL 停止进程(此信号不能 ...

随机推荐

  1. Istio技术与实践03:最佳实践之sidecar自动注入

    Istio通过对serviceMesh中的每个pod注入sidecar,来实现无侵入式的服务治理能力.其中,sidecar的注入是其能力实现的重要一环(本文主要介绍在kubernetes集群中的注入方 ...

  2. sqlserver时间戳

    SELECT DATEADD(S,1576464113 + 8 * 3600,'1970-01-01 00:00:00') --时间戳转换成普通时间 SELECT DATEDIFF(S,'1970-0 ...

  3. jdk8的环境配置

    下载jdk,选择安装路径进行安装.https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.htm ...

  4. Centos7 配置 svn服务端

    转载至:Linux(阿里云Centos7)环境下搭建svn服务器以及权限配置详细步骤 本篇文章主要介绍在CentOS7中采用yum安装方式.优点:简单,一键安装,不用手动配置环境变量等.缺点:安装位置 ...

  5. Linux下zookeeper集群搭建

    Linux下zookeeper集群搭建 部署前准备 下载zookeeper的安装包 http://zookeeper.apache.org/releases.html 我下载的版本是zookeeper ...

  6. Vue下的index.html

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  7. 1118 DOM

    目录 BOM与DOM window对象 navigator对象(了解即可) screen对象(了解即可) history对象(了解即可) location对象 弹出框 计时相关 DOM对象 DOM结构 ...

  8. TCP的三次握手与四次挥手的理解

    本文经过借鉴书籍资料.他人博客总结出的知识点,欢迎提问    序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生:给字节编上 ...

  9. IPC五种通讯方式

    IPC五种通讯方式 1.管道:速度慢,容量有限,只有父子进程能通讯 2.FIFO:任何进程间都能通讯,但速度慢 3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题 ...

  10. docker换源

    方案一 修改或新增 /etc/docker/daemon.json # vi /etc/docker/daemon.json { "registry-mirrors": [&quo ...