引言

先看以下两个信号量:

13)SIGPIPE     当管道读端关闭,再往管道写东西,会发出SIGPIPE信号
17)SIGCHLD   子进程退出会向父进程发出SIGCHLD信号,系统默认处理是忽略掉该信号

代码

/*************************************************************************
> File Name: my_fork.c
> Author: KrisChou
> Mail:zhoujx0219@163.com
> Created Time: Mon 25 Aug 2014 10:42:26 AM CST
************************************************************************/ #include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <signal.h>
void handler(int num)
{
pid_t pid ;
printf("sig_num: %d \n", num);
pid = wait(NULL);
printf("wait : %u \n", pid);
}
int main(int argc, char* argv[])
{
int fds[2];// fds[0] r fds[1] w
pipe(fds);
char buf[1024];
signal(SIGPIPE, handler);
signal(SIGCHLD, handler);
if(fork() == 0)
{
close(fds[1]);
while(memset(buf, 0, 1024), read(fds[0], buf, 1024))
{
write(1, buf, strlen(buf));
}
printf("child over ! \n");
exit(0);
}
if(fork() == 0)
{
exit(0);
}
if(fork() == 0)
{
exit(0);
}
close(fds[0]) ;
while(memset(buf, 0, 1024), read(0, buf, 1024))
{
write(fds[1], buf, strlen(buf));
}
//while(1) ;
return 0 ;
}

运行结果如下:

[purple@localhost review]$ ./a.out
sig_num: 17
wait : 15693
sig_num: 17
wait : 15692
hello
hello
world!
world!
child over !

程序运行时,先是两个子进程先后退出,向父进程发送SIGCHLD 信号,接着执行handler函数,回收两个子进程资源。接着程序执行到父进程的while循环,由于read是阻塞函数,在我们没有按下enter或者ctrl+d之前,时间片会在第一个子进程和父进程之间来回切换。如果输入字符按enter,那么也就是父进程将其写入管道,子进程将其从管道中取出,并显示在屏幕上。

如果按ctrl+d,则父进程退出while循环,并且退出程序。此时第一个子进程成为孤儿进程,被init收养,子进程退出时,会向init发送SIGCHLD 信号,由init回收资源。(注意,init很猛的,它本身就已经将SIGCHLD 注册了,其信号处理函数实现了回收资源)

干货

我们之所以将回收子进程资源的wait函数写在信号处理函数中,是因为wait是阻塞函数。如果父进程阻塞了就不能处理自己的工作了。

之前我们已经提过,当子进程终止时,会给父进程发送SIGCHLD信号,虽然该信号的默认处理动作是忽略,但是父进程可以自定义SIGCHLD信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程,当子进程终止时会通知父进程,父进程在信号处理函数中调用wait清理子进程资源即可。

通常情况下服务器是永远不会退出的,因此我们可以在之前的程序中 return 0 前加个while(1),以此来模拟服务器。

注意

如果父进程先于子进程退出,则子进程成为孤儿进程,此时将自动被PID为1的进程(即init)接管。孤儿进程退出后,它的清理工作有祖先进程init自动处理。但在init进程清理子进程之前,它一直消耗系统的资源,所以要尽量避免。

如果子进程先退出,系统不会自动清理掉子进程的环境,而必须由父进程调用wait或waitpid函数来完成清理工作,如果父进程不做清理工作,则已经退出的子进程将成为僵尸进程(defunct),在系统中如果存在的僵尸(zombie)进程过多,将会影响系统的性能,所以必须对僵尸进程进行处理。

Linux信号处理2的更多相关文章

  1. linux 信号处理 五 (示例)

    [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...

  2. linux信号处理相关知识

      因为要处理最近项目中碰上的多个子进程退出信号同时到达,导致程序不当产生core的情况,今天我花了时间看了一些关于linux信号处理的博客. 总结一下:(知识未经实践) linux信号分两种,一种实 ...

  3. linux 信号处理 四

    一.信号生命周期 从信号发送到信号处理函数的执行完毕 对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个重要的阶段,这三个阶段由四个重要事件来刻画:信号诞生:信号在进程 ...

  4. linux 信号处理 六(全)

    一.信号及信号来源 信号本质 信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实 ...

  5. linux 信号处理 三 (信号集的使用)

    sigprocmask系统调用 使用条件: 1.有时候不希望在接到信号时就立即停止当前执行,去处理信号,同时也不希望忽略该信号,而是延时一段时间去调用信号处理函数.这种情况是通过阻塞信号实现的. 2. ...

  6. linux 信号处理 一 (基本概念)

    信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全 ...

  7. Linux信号处理编程

    01. 学习目标 了解信号中的基本概念 熟练使用信号相关的函数 了解内核中的阻塞信号集和未决信号集作用 熟悉信号集操作相关函数 熟练使用信号捕捉函数signal 熟练使用信号捕捉函数sigaction ...

  8. linux信号处理时机

    信号号称所谓软中断,事实上,还是没有真正的硬件中断那样能随时改变cpu的执行流 硬件中断之所以能一发生就得到处理是因为处理器在每个指令周期的结尾都会去检查中断,这种粒度是很细的 但是信号的实现只是在进 ...

  9. Linux信号处理

    给进程设置僵尸状态的目的是维护子进程的信息,以便父进程在以后某个时间获取.这些信息包括子进程的进程ID.终止状态以及资源利用信息(CPU时间,内存使用量等等).如果一个进程终止,而该进程有子进程处于僵 ...

  10. linux信号处理及libcurl的坑

    前言:     最近有个项目, 需要访问第三方服务. 该服务是通过http的形式访问的, 为了安全和加密, 对方提供了一个加密用的C/C++库, 用于对参数进行处理.  鉴于此, 选用了C/C++语言 ...

随机推荐

  1. Go中简单的文件读写

    Go中的ioutil包可以方便的实现文件读写.代码: package main import ( "fmt" "io/ioutil" ) func main() ...

  2. IOS应用程序升级

    IOS应用程序升级流程介绍:IOS手机端应用程序需要升级时,打开服务器端html文件(本文为ucab.html文件)->点击在线安装->打开plist文件(本文中为ucab.plist文件 ...

  3. mac中添加环境变量

    sudo vi /etc/paths 来编辑 paths,将环境变量添加到 paths 中. vim 是一个编辑器,另外还有几个,如:Pico,Emacs.  

  4. jquery页面刷新reload

    今天知道了jquery页面刷新的一个方法,很简单的一句: window.location.reload()刷新当前页面,不得不说我jquery学的很糟糕,明明都学过,但是等用到的时候就想不起来了.不过 ...

  5. UIDatePicker swift

    // // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...

  6. 修改ip脚本

    1.打开运行 2.输入CMD 3.在命令提示符下输入: netsh -c interface ip dump > C:\我的网络配置.txt 4.打开您在C:\ 下的"我的网络配置 . ...

  7. Notes of the scrum meeting(12.8)

    meeting time:18:00~18:30p.m.,December 8th,2013 meeting place:20号公寓前 attendees: 顾育豪                   ...

  8. Material

    renderer.material  物理材质 实现二维图上的人物动作 新建Material,选择Shader(著色器)为transparent/diffuse(背景透明),将上图拉到背景图选项中. ...

  9. gameObject, vector and transform

    调用其它组件中成员 通过GameObject(游戏物体). Base class for all entities in Unity scenes.  是Unity场景里面所有实体的基类. 可以理解为 ...

  10. 我存在,你深深的循环里--从反射看JSON死循环

      JSON有一个非常经典的问题:JSONException: There is a cycle in the hierarchy!俗称死循环.解决这个问题至少有三种以上的办法,总之一句话就是过滤.今 ...