信号处理程序(signal handler)会被重置的信号
首先说明我的系统,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)会被重置的信号的更多相关文章
- 信号之signal函数
UNIX系统的信号机制最简单的接口是signal函数.signal函数的功能:为指定的信号安装一个新的信号处理函数. #include <signal.h> void (*signal(i ...
- Linux信号(signal) 机制分析
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
- 信号(signal)
1.信号本质 1)信号是一种软件中断,是在软件层次上对中断的模拟: 2).在日常生活中也有很多信号,比如常见的红绿灯信号,我们看见红灯就停下,linux中的信号也是类似的,它提供一种机制告诉某个进程在 ...
- Linux信号(signal) 机制分析(转)
[摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...
- [学习笔记]信号基本概念(中断和信号)/名称及常用信号/信号处理/signal函数实践
1基本概念 中断 q 中断是系统对于异步事件的响应 q 中断信号 q 中断源 q 现场信息 q 中断处理程序 q 中断向量表 异步事件的响应:进程执行代码的过程中可以随时被打断,然后去执行 ...
- Linux信号(signal) 机制分析-(转自h13)
[摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...
- 【转贴】gdb中的信号(signal)相关调试技巧
一篇不错的帖子,讲的是gdb中的信号(signal)相关调试技巧 转自Magic C++论坛 http://www.magicunix.com/index_ch.html http://www.m ...
- signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数
信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...
- APUE 3 -- 信号 (signal)<II>: 可靠信号
一个事件可以事一个信号发送给一个进程,这个事件可以是硬件异常,可以是软件条件触发,可以是终端产生信号,也可以是一个kill函数调用.当信号产生后,内核通常会在进程表中设置某种形式的标志(flag).我 ...
随机推荐
- Linux常用命令速查备忘
Linux常用命令速查备忘 PS:备忘而已,详细的命令参数说明自己man 一. 启动,关机,登入,登出相关命令 [login] 登录 [logout] 登出 [exit] 登出 [shutdown ...
- [Javascript] “||”和“&&”的灵活运用
引用URL : http://my249645546.iteye.com/blog/1553202 你是否看到过这样的代码:a=a||""; 可能javascript初学者会对此感 ...
- Java基础知识强化之IO流笔记77:NIO之 Selector
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 1. ...
- 【Java的JNI快速学习教程】
1. JNI简介 JNI是Java Native Interface的英文缩写,意为Java本地接口. 问题来源:由于Java编写底层的应用较难实现,在一些实时性要求非常高的部分Java较难胜任(实时 ...
- MS SQL SERVER 中的系统表
MS SQL SERVER 中的系统表 序号 名称 说明 备注 1 syscolumns 每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行. 2 syscomments 包含每 ...
- Windows8不联网直接安装.Net 3.5 Framework的方法
把你的系统ISO加载到虚拟光驱或插入系统安装盘,找到X:\sources\sxs路径(X是你的光驱盘符).输入下面命令,盘符以D盘为例DISM /Online /Enable-Feature /Fea ...
- 关于如何用sql语句查询出连续的一串数字
在数据库操作中,经常有一些这样的操作:插入诺干条测试数据.查询这个月的登录情况(没有登录的日期不能不存在,要显示数量为0),获取诺干条guid. 这些的基础都是怎么生成连续的一串数字 1 2 3 ...
- javascript组件开发之基类继承实现
上一篇文章大概的介绍了一下关于javascript组件的开发方式,这篇文章主要详细记一下基类的编写,这个基类主要是实现继承的功能 为什么要封装基类? 由于这次重构项目需要对各种组件进行封装,并且这些组 ...
- WPF全球化与本地化 (二)
Visual Baml Visual Locbaml is a free and open-source software to simplify the task of WPF applicatio ...
- 剑指Offer08 二进制中1的个数
/************************************************************************* > File Name: 08_NumOf1 ...