信号处理程序(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服务器集群系统(一)--转
引用地址:http://www.linuxvirtualserver.org/zh/lvs1.html LVS项目介绍 章文嵩 (wensong@linux-vs.org)2002 年 3 月 本文介 ...
- java 数组初始化
一维数组 1) int[] a; //声明,没有初始化 2) int[] a=new int[5]; //初始化为默认值,int型为0 3) int[] a={1,2,3,4,5} ...
- LeetCode25 Reverse Nodes in k-Group
题意: Given a linked list, reverse the nodes of a linked list k at a time and return its modified list ...
- 使用Thread类可以创建和控制线程
1.创建线程 static void Main(string[] args) { /* Thread类 * 创建控制线程 * 其构造函数接受ThreadStart和ParameterizedThrea ...
- velocity 随笔
资源网站: http://wiki.apache.org/velocity/ http://velocity.apache.org/engine/releases/velocity-1.7/user- ...
- SQL 必知必会-- 第17课:创建和操作表
我这里用的是oracle 10g,PL/SQL来做的. 第17课 创建和操纵表 14517.1 创建表 14517.2 更新表 15017.3 删除表 15317.4 重命名表 1 ...
- [PHP] htaccess 探秘
.htaccess访问控制(Allow/Deny) 1. 验证是否支持.htaccess 在目录下新建一个.htaccess 文件,随笔输入一串字符(毫无意义),看看什么反应,如果是500错误,说明目 ...
- 【Mood-11】值得学习的国内外Android开发者信息
国内 Android 开发者信息: 昵称 GitHub 博客 介绍 罗升阳 Luoshengyang@csdn Android 源码分析 邓凡平 innost@csdn 阿拉神农 魏祝林 ...
- 手机端Post 数据
var data =""; using (StreamReader readStream = new StreamReader(context.Reques ...
- XE5 Android 开发数据访问手机端 解决乱码的办法
经过测试,将sqlserver里的字段由varchar 或者char 改为 nvarchar 或者nchar 然后在手机端的clientdataset 增加字段的时候数据类型选择widestrin ...