首先说明我的系统,CentOS 6.6,内核为2.6.32-504.12.2.el6.i686。

  当用signal对某个信号设定信号处理函数的时候,有些信号的处理函数会被重置,有些则不会,这种情况的具体说明我还没有找到,这里我就先列一下我找到的几个信号。

  信号处理程序会被重置的信号:

  1. SIGALRM

    比如下面这段代码,这段代码的作用就是给自己发送SIGALRM信号,直到发送了NUM次。

 #include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h> #define BUFSIZE 512
#define NUM 5 /*
* 这三个函数是我自定义的,功能就是利用strerror打印errno的信息,并且退出
*/
void err_exit(char *fmt,...);
int err_dump(char *fmt,...);
int err_ret(char *fmt,...); int alrm_count = ; //对发送的alrm信号进行计数
/*
* 本函数用来处理SIGALRM信号
*/
void sig_alrm(int signo)
{
alrm_count++;
printf("In signal SIGALRM handler\n");
if(SIG_ERR == signal(SIGALRM,sig_alrm))
err_exit("[signal]: ");
if(alrm_count < NUM) {
alarm();
pause();
}
} int main(int argc,char *argv[])
{
if(SIG_ERR == signal(SIGALRM,sig_alrm))
err_exit("[signal]: "); /*alarm函数的功能就是在1s之后向本进程发送一个SIGALRM信号*/
alarm();
pause(); return ;
}

  这个程序的29~30行就是在信号的处理函数中重新设置对SIGALRM的处理函数,下次产生SIGALRM这个信号的时候,继续来调用这个处理函数。程序的运行结果如下:

  

  如果没有29~30行那两行的内容,程序的运行结果就会变成下面这样:

  

  第一次接受到SIGALRM信号,程序会调用我们自定义的sig_alrm信号处理函数,但是第二次接受到SIGALRM信号的时候,程序就会调用系统默认的SIGALRM的信号处理函数了,此时就会打印出Alarm clock信息。

  2. SIGCHLD信号(SIGCLD)

    在linux下面,这两个信号是等价的,所以就放在一起来讨论。首先先把代码贴上来:

 #include <errno.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h> #define BUFSIZE 512
#define NUM 2 void err_exit(char *fmt,...);
int err_dump(char *fmt,...);
int err_ret(char *fmt,...); void sig_chld(int signo); int main(int argc,char *argv[])
{
pid_t pid; if(SIG_ERR == signal(SIGCHLD,sig_chld))
perror("[signal]: "); for(int loop=;loop<NUM;loop++) {
if(- == (pid=fork())) {
err_exit("[fork]:");
} else if( == pid) {
printf("I'm the No.%d Child %d\n",loop+,getpid());
return ;
} else {
pause();
}
} return ;
} void sig_chld(int signo)
{
int status;
pid_t cpid; /* printf("A child process terminated!\n"); */
if(- == (cpid=wait(&status)))
err_exit("[wait]: ");
else
printf("Process %d terminated!\n",cpid); if(SIG_ERR == signal(SIGCHLD,sig_chld))
perror("[signal]: ");
}

  这段代码的作用就是父进程创建一个子进程,然后暂停,等待子进程结束发送SIGCHLD信号过来,在SIGCHLD信号的信号处理函数中,将子进程回收,并且打印出回收的子进程进程id。执行完这些步骤之后,再来继续这个过程,直到循环了NUM次。

  这个程序的运行结果如下所示:

  

  这里可以看到,两个子进程结束时发送的SIGCHLD信号都被接受到了,并且两个子进程都被回收了。

  如果我去掉了在信号处理函数中的signal函数(52~53行),那么程序的运行结果就会如下图所示:

  

  主函数卡死了,此时我用top命令来查看这进程信息,发现第二个子进程变成了僵尸进程,如下图所示:

  

  此时SIGCHLD信号处理函数,变成了默认的忽略(SIG_IGN),接受到了SIGCHLD信号就不会调用函数了,而pause函数的说明则是这样的:

  

  pause函数只有遇到让主进程终止的信号,或者是产生信号处理函数调用的函数才会停止睡眠。而在上面的程序中,第二次的时候SIGCHLD信号由于采用的系统默认的配置SIG_IGN,此时不会产生信号处理函数的调用,所以主进程就继续暂停。

  信号处理程序不会被重置的信号:

  目前我只发现了两个,就是两个用户自定义的函数,SIG_USR1和SIG_USR2,具体可以参看下面这段代码:

 #include<errno.h>
#include<signal.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>
#include<stdio.h>
#include<unistd.h> #define BUFSIZE 512 /*
* 这三个函数是我自定义的,功能就是利用strerror打印errno的信息,并且退出
*/
void err_exit(char *fmt,...);
void err_dump(char *fmt,...);
int err_ret(char *fmt,...); void sig_handler(int signo)
{
if(signo == SIGUSR1)
  printf("Catch the SIGUSR1 [%d]\n",signo);
else if(signo == SIGUSR2)
  printf("Catch the SIGUSR2 [%d]\n",signo);
else
  err_dump("Catch the signal %d\n",signo);
}
int main(int argc,char *argv[])
{
if(SIG_ERR == signal(SIGUSR1,sig_handler))
  err_exit("[signal]1: ");
if(SIG_ERR == signal(SIGUSR2,sig_handler))
  err_exit("[signal]2: "); for(;;)
  pause(); return ;
}

  这个程序就是一直等待信号发送过来,并且会对SIGUSR1和SIGUSR2进行处理,其他信号则会执行系统默认的处理情况。运行的结果如下图:

  程序开始后,我通过另一个终端给这个程序发送信号,如下图所示:

  

  而程序运行的界面如下图所示:

  

  从这里可以看出,我们只对SIGUSR这两个函数设置了一次信号处理函数,但是它们的处理方式就不会被重置,发送多次SIGUSR信号都是同一种处理方式。

信号处理程序(signal handler)会被重置的信号的更多相关文章

  1. 信号之signal函数

    UNIX系统的信号机制最简单的接口是signal函数.signal函数的功能:为指定的信号安装一个新的信号处理函数. #include <signal.h> void (*signal(i ...

  2. Linux信号(signal) 机制分析

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

  3. 信号(signal)

    1.信号本质 1)信号是一种软件中断,是在软件层次上对中断的模拟: 2).在日常生活中也有很多信号,比如常见的红绿灯信号,我们看见红灯就停下,linux中的信号也是类似的,它提供一种机制告诉某个进程在 ...

  4. Linux信号(signal) 机制分析(转)

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

  5. [学习笔记]信号基本概念(中断和信号)/名称及常用信号/信号处理/signal函数实践

    1基本概念 中断 q  中断是系统对于异步事件的响应 q  中断信号 q  中断源 q  现场信息 q  中断处理程序 q  中断向量表 异步事件的响应:进程执行代码的过程中可以随时被打断,然后去执行 ...

  6. Linux信号(signal) 机制分析-(转自h13)

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

  7. 【转贴】gdb中的信号(signal)相关调试技巧

    一篇不错的帖子,讲的是gdb中的信号(signal)相关调试技巧 转自Magic C++论坛  http://www.magicunix.com/index_ch.html  http://www.m ...

  8. signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数

    信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...

  9. APUE 3 -- 信号 (signal)<II>: 可靠信号

    一个事件可以事一个信号发送给一个进程,这个事件可以是硬件异常,可以是软件条件触发,可以是终端产生信号,也可以是一个kill函数调用.当信号产生后,内核通常会在进程表中设置某种形式的标志(flag).我 ...

随机推荐

  1. iOS缓存框架-PINCache解读

    文/Amin706(简书作者)原文链接:http://www.jianshu.com/p/4df5aad0cbd4著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 在项目中总是需要缓存一 ...

  2. TinyThread源码分析之中断

    转载请注明来源:cuixiaolei的技术博客 https://github.com/xhawk18/TinyThread TinyThread 是基于Cortex-M0的小型的OS. 知识储备: I ...

  3. [原创] Web UI自动化应用测试框架实践 - 概览

    之前为我们部门做的一个UI框架.不能纯粹解读为框架,主要是做了一些简单的分层设计,以解决稳定性.降低复杂性.提升可维护性以及快速构建测试用例等实际问题. 主要部分:1. 测试数据.主要提供测试类库需要 ...

  4. 从敏捷开发到小团队SVN

    一.敏捷之惑 敏捷开发,有一个很好的实践,“每天都可以产生一个可用于发布的版本”. 以前对这句话感到非常的困惑,因为我们手中的项目是残缺的,基本只是程序的一个功能片段,在未集成之前如何发布得了?当然这 ...

  5. JavaScript字符串分割方法

    使用split('')方法.此方法与Java的字符串分割方法方法名一样.

  6. HTML标签大全

    HTML标签解释大全 一.HTML标记 标签:!DOCTYPE 说明:指定了 HTML 文档遵循的文档类型定义(DTD). 标签:a 说明:标明超链接的起始或目的位置. 标签:acronym 说明:标 ...

  7. android app性能优化大汇总(内存性能优化)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...

  8. CSS之自适应布局webkit-box

    自适应布局webkit-box,在平常的web横排布局中,会经常用到float或display:inline-block,但是在多种不同宽度的移动设备的自适应布局中用的话,还得设置百分比宽度和考虑清除 ...

  9. 北大ACM(POJ1010-STAMPS)

    Question:http://poj.org/problem?id=1010问题点:DFS.剪枝. Memory: 220K Time: 32MS Language: C++ Result: Acc ...

  10. js 数组的length(javascript教程四)

    这是一个简单的函数,就是利用length来判断数组再遍历数组了. <script language="javascript" type="text/javascri ...