捕抓信号

如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,称为捕抓信号。

除了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的更多相关文章

  1. Signal ()函数详细介绍

    1. 功能 设置某一信号的对应动作 2. 声明 #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t si ...

  2. signal()信号操作

    一.函数描述 #include <signal.h> typedef void (*sighandler_t)(int);sighandler_t signal(int signum, s ...

  3. gdb 常用内容

    gdb exegdb exe coregdb -p info m TAB ^関数の先頭 info b ^list the breakpoint set args -a test ^引数設定 show ...

  4. Linux信号

    信号本质上就是一个软件中断,它既可以作为两个进程间的通信的方式, 更重要的是, 信号可以终止一个正常程序的执行, 通常被用于处理意外情况 ,* 信号是异步的, 也就是进程并不知道信号何时会到达 $ki ...

  5. Linux信号基础

    Linux信号基础   作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux进程基础一文中已经提到,Linux以进程为单位来 ...

  6. Linux 进程

    Linux 进程 在用户空间,进程是由进程标识符(PID)表示的.从用户的角度来看,一个 PID 是一个数字值,可惟一标识一个进程.一个 PID 在进程的整个生命期间不会更改,但 PID 可以在进程销 ...

  7. Linux进程间通信-信号

    1.什么是信号信号是Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会执行相应的操作. 2.信号的产生1)由硬件产生,如从键盘输入Ctrl+C可以终止当前进程2)由其他进程发送,如可在s ...

  8. MySQL在ROW模式下通过binlog提取SQL语句

    Linux基于row模式的binlog,生成DML(insert/update/delete)的rollback语句通过mysqlbinlog -v 解析binlog生成可读的sql文件提取需要处理的 ...

  9. Linux简单程序实例(GNU工具链,进程,线程,无名管道pipe,基于fd的文件操作,信号,scoket)

    一, GNU工具链简介: (1)编译代码步骤: 预处理 -> 编译 -> 汇编 -> 链接: 预处理:去掉注释,进行宏替换,头文件包含等工作: gcc -E test.c -o te ...

随机推荐

  1. 通过Intel XDK编写跨平台app(一)

    Intel XDK 是一个新的跨平台手机应用开发工具.它努力把整个开发流程变的简单,尽可能把所有的平台都封装到一个包中,通过收集各种开发工具来使你的开发变的简单. 在这篇文章中,我将会向你介绍什么是I ...

  2. angular中定义全局变量及全局变量的使用

    一个例子,定义了两个变量,并且把变量显示出来: <!DOCTYPE html> <html ng-app="myApp"> <head> < ...

  3. STL - 函数作为算法的参数

    函数作为参数,相当于C++的函数指针, C#的委托 for_each函数参数: #include <iostream> #include <algorithm> #includ ...

  4. shareSDK(分享第三方库)的 使用

    首先,下载第三方库,可以去官网下载,官网的地址我忘记了,但下面有一个我之前下的和我写的例子,其实官方的例子也写我们只是告诉大家用时需要把哪些代码复制出来就可以用了. 1.导入如下框架和第三方库 新浪微 ...

  5. tomcat启动报错,找不到相应的 queue,从而引发内存泄漏

    tomcat启动报错,无法创建 bean listenerStatusChangeDealHandler, no queue 'STOCK.NOTIFY_CHANGE.INTER.CACHE.QUEU ...

  6. Openerp workflow 工作流批注模块

    转自:http://blog.csdn.net/yeahliu/article/details/17207289 2013-12-22 添加workflow_stop标识,感谢广州-jerry 201 ...

  7. 这些小工具让你的Android 开发更高效

    在做Android 开发过程中,会遇到一些小的问题.尽管自己动手也能解决.可是有了一些小工具,解决这些问题就得心应手了,今天就为大家推荐一下Android 开发遇到的小工具,来让你的开发更高效. Vy ...

  8. window.onunload | window.onbeforeunload

    先引述一段jQuery 官方对于onunload的评述: The unload event is sent to the window element when the user navigates ...

  9. [bug]未能从程序集“System.ServiceModel, Version=3.0.0.0问题解决

    在Windows Server 2008中的IIS服务器中部署WCF服务程序时,通过浏览器访问报出如下错误: 未能从程序集“System.ServiceModel, Version=3.0.0.0, ...

  10. 摘:C++ 枚举类型

    C++ 中的枚举类型继承于 C 语言.就像其他从 C 语言继承过来的很多特性一样,C++ 枚举也有缺点,这其中最显著的莫过于作用域问题——在枚举类型中定义的常量,属于定义枚举的作用域,而不属于这个枚举 ...