捕抓信号

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

除了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. CentOS7 rpm方式安装mysql5.7

    内容源自:CentOS7安装mysql 在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB. 1. ...

  2. 【精】iOS6 及其以上版本号自己主动旋转、手动强制旋转方案及布局适配

    1.布局适配方式 本文不讨论哪种布局适配方式最好.此处使用的是 Masonry 纯代码布局适配. (Masonry 底层就是 AutoLayout 的 NSLayoutConstraint) 2.iO ...

  3. Units specified don't exist SHSUCDX can't install

    重装系统,出现“Units specified don't exist SHSUCDX can't install”怎么办? 昨天,我们领导弄了个联想Thinkpad T510i的笔记本,本来预装的是 ...

  4. python分号使用

    一:python分号使用 每一条语句最后个加个分号:这是c,oc,java,php等语言中不可缺少的部分,但是对于python,分号是可加,可不加的 如:不加分号代码 >>> cla ...

  5. 【转】如何成为Python高手

    http://www.aqee.net/how-to-become-a-proficient-python-programmer/ 这篇文章主要是对我收集的一些文章的摘要.因为已经有很多比我有才华的人 ...

  6. Cocos2d-x 3.2 Lua演示样例 AssetsManagerTest(资源管理器)

    Cocos2d-x 3.2 Lua演示样例 AssetsManagerTest(资源管理器) 本篇博客介绍Cocos2d-x 为我们提供的一个类--AssetsManager在Lua中的使用样例,效果 ...

  7. knockoutjs 静动态数据、行为绑定,计算属性及Sync同步更新 Value值更新事件控制

    data-bind="text: firstName"中data-bind属性是Knockout 用来显示关联UI和viewmodel的桥梁, text 表示把绑定的文本赋值给DO ...

  8. index.js

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  9. Android 自己定义View (四) 视频音量调控

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24529807 今天没事逛eoe,看见有人求助要做一个以下的效果,我看以下一哥们说 ...

  10. 后台Post/Get 请求接口 方式

    Post请求 public string HttpPost(string Url, string postDataStr) { try { HttpWebRequest request = (Http ...