catch signal
捕抓信号
如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,称为捕抓信号。
除了SIGSTOP和SIGKILL进程能够忽略或捕获其他的全部信号。
注:信号可从两个不同分类角度对信号进行分类,1)可靠性方面:可靠信号与不可靠信号;2)与时间的关系上:实时信号与非实时信号。常见的信号1-31都是不可靠信号,都是非实时信号。
sighandler和main函数默认使用相同的堆栈空间,sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。内核态切换到用户态执行main函数前要先扫描信号,处理信号后再执行main函数部分。
信号可以嵌套执行,这也是信号屏蔽的原因(在信号处理函数中,或关键处理时,不能被其他信号打断,从而处理其他信号)----自我理解
- 发送信号kill
#include <signal.h>
int kill(pid_t pid, int signo);
- 注册信号处理signal(不推荐)
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- 发送信号sigqueue
- 注册信号处理函数sigaction
int sigaction(int signo, const struct sigaction *act, struct sigaction *lact);
成功0, 失败-1.
注:signo不可为信号SIGKILL和SIGSTOP
struct sigaction {
void (*sa_handler)(int); /* or SIG_IGN, SIG_DFL */
sigset_t sa_mask; /*addition signals to block*/
int sa_flags; /*0则信号处理函数为sa_handler();SA_SIGINFO,信号处理函数为sa_sigaction*/
void (*sa_sigaction)(int, siginfo_t *, void *);
};
sa_mask specifies a mask of signals which should be blocked (i.e., added to the signal mask of the thread in which the signal handler is invoked) during execution of the signal handler.
In addition, the signal which triggered the handler will be blocked, unless the SA_NODEFER flag is used.
示例
主程序所有信号都注册新捕捉函数,然后捕抓函数中恢复默认动作。
19 void do_signal(int signo)
20 {
21 struct sigaction act;
22 int ret;
23
24 printf("catch signo %d.\n", signo);
25 26 act.sa_handler = SIG_DFL;
27 sigemptyset(&act.sa_mask);
28 act.sa_flags = 0;
29 ret = sigaction(signo, &act, NULL);
30 if(ret < 0){
31 perror("sigaction error");
32 exit(EXIT_FAILURE);
33 } 34 35 raise(signo);
36 }
46 int sigi;
47 int ret;
48 struct sigaction new_act;
49 50 new_act.sa_handler = do_signal;
51 sigemptyset(&new_act.sa_mask);
52 new_act.sa_flags = 0; 53 54 for(sigi=1; sigi<=SIG_NUM; sigi++){
55 if((sigi == SIGKILL) || (sigi == SIGSTOP))
56 continue; 57 58 ret = sigaction(sigi, &new_act, NULL);
59 if(ret < 0){
60 perror("main sigaction error");
61 exit(EXIT_FAILURE);
62 }else{
63 // printf("%d signal is registered.\n", sigi);
64 }
65 }
信号执行
通过编程观察到常用信号(1-31)有如下执行行为:
1)没有屏蔽任何信号时,任何信号都可以到达,并首先完成最后一个信号的执行,然后再完成原来信号函数剩余部分。(信号嵌套)
2)在信号执行过程中,再次(或多次)触发相同信号,则该信号不会立即执行(阻塞相同信号),在原来信号执行完后,仅再执行一次信号处理函数。
3)在一个信号执行周期内(程序未返回main函数执行),若执行过程中触发了多个信号,则首先执行完最后一个信号,然后倒序依次执行信号一次。
通过上述观察,可知:重复的信号仅执行一次。
究其原因,是因为非实时信号的实现方式。
当一个非实时信号发送给一个进程时,如果该信号已经在进程中注册,则该信号将被丢弃,造成信号丢失。因此,非实时信号又叫做"不可靠信号"。这意味着同一个非实时信号在进程的未决信号信息链中,至多占有一个sigqueue结构(一个非实时信号诞生后,(1)如果发现相同的信号已经在目标结构中注册,则不再注册,对于进程来说,相当于不知道本次信号发生,信号丢失;(2)如果进程的未决信号中没有相同信号,则在进程中注册自己)。
当一个实时信号发送给一个进程时,不管该信号是否已经在进程中注册,都会被再注册一次,因此,信号不会丢失,因此,实时信号又叫做"可靠信号"。这意味着同一个实时信号可以在同一个进程的未决信号信息链中占有多个sigqueue结构(进程每收到一个实时信号,都会为它分配一个结构来登记该信号信息,并把该结构添加在未决信号链尾,即所有诞生的实时信号都会在目标进程中注册)。
可参考:
http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html
catch signal的更多相关文章
- Signal ()函数详细介绍
1. 功能 设置某一信号的对应动作 2. 声明 #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t si ...
- signal()信号操作
一.函数描述 #include <signal.h> typedef void (*sighandler_t)(int);sighandler_t signal(int signum, s ...
- gdb 常用内容
gdb exegdb exe coregdb -p info m TAB ^関数の先頭 info b ^list the breakpoint set args -a test ^引数設定 show ...
- Linux信号
信号本质上就是一个软件中断,它既可以作为两个进程间的通信的方式, 更重要的是, 信号可以终止一个正常程序的执行, 通常被用于处理意外情况 ,* 信号是异步的, 也就是进程并不知道信号何时会到达 $ki ...
- Linux信号基础
Linux信号基础 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux进程基础一文中已经提到,Linux以进程为单位来 ...
- Linux 进程
Linux 进程 在用户空间,进程是由进程标识符(PID)表示的.从用户的角度来看,一个 PID 是一个数字值,可惟一标识一个进程.一个 PID 在进程的整个生命期间不会更改,但 PID 可以在进程销 ...
- Linux进程间通信-信号
1.什么是信号信号是Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会执行相应的操作. 2.信号的产生1)由硬件产生,如从键盘输入Ctrl+C可以终止当前进程2)由其他进程发送,如可在s ...
- MySQL在ROW模式下通过binlog提取SQL语句
Linux基于row模式的binlog,生成DML(insert/update/delete)的rollback语句通过mysqlbinlog -v 解析binlog生成可读的sql文件提取需要处理的 ...
- Linux简单程序实例(GNU工具链,进程,线程,无名管道pipe,基于fd的文件操作,信号,scoket)
一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o te ...
随机推荐
- 转: Mac 使用ADT的问题
http://blog.csdn.net/wwj_748/article/details/44806253
- TeamTalk 5
TeamTalk 5 Repository for TeamTalk 5 development. Download TeamTalk 5 SDK To build the TeamTalk clie ...
- 《javascript高级程序设计》读书笔记(一)javascript简单介绍
第一章:javascript简单介绍 Netscape Navigator 开发的javascript Javascript的实现有三部分: 1.核心(ECMAScript):提供核心语言功能. ...
- Linux下显示硬盘空间的两个命令
1.df -h ,用于显示目前所有文件系统的可用空间及使用情况,示例如下: [root@msg45 ~]# df -hFilesystem Size Used ...
- Python 多重循环
# coding=gbk LOL1 = ['OMG', 'EDG', '皇族'] LOL2 = ['韩国', '欧洲', '美国'] for l1 in LOL1: for l2 in LOL2: p ...
- 利用SQL语句重置数据库中所有表的标识列(自增量)
可以应用于2种场景: 1.清空所有表中的数据,数据清空后,最好是能够让表中的标识列从1开始记数,所以要重置标识列的当前值. 2.用复制的方式,发布订阅同步数据之后,订阅端的数据不会自动增长,比如自增I ...
- FastDFS简易概括
FastDFS是一个文件系统,可以部署在Linux上. 该文件系统具备高可用和负载均衡特性,还可以动态扩充容量. 此文件系统有两个服务组成:跟踪服务和存储服务,也就是说你必须部署了这两种服务,这个文件 ...
- 基于Django的在线考试系统
概述 基于Django的在线考试系统,适配电脑端,可以实现出题,答题,排行榜,倒计时等等等功能 详细 代码下载:http://www.demodashi.com/demo/13923.html 项目目 ...
- mysql(表类型的选择)
1.查询mysql所支持的存储引擎 第一种方法:show engines \G
- C#指南,重温基础,展望远方!(10)C#枚举
枚举类型是包含一组已命名常量的独特值类型. 需要定义包含一组离散值的类型时,可以定义枚举. 枚举使用一种整型值类型作为其基础存储, 并提供离散值的语义含义. 以下示例声明并使用名为“Color”的 e ...