转自:http://gityuan.com/2015/12/20/signal/

信号(signal)是一种软中断,信号机制是进程间通信的一种方式,采用异步通信方式

一、信号类型

Linux系统共定义了64种信号,分为两大类:可靠信号与不可靠信号,前32种信号为不可靠信号,后32种为可靠信号。

1.1 概念

  • 不可靠信号: 也称为非实时信号,不支持排队,信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次. 信号值取值区间为1~31;

  • 可靠信号: 也称为实时信号,支持排队, 信号不会丢失, 发多少次, 就可以收到多少次. 信号值取值区间为32~64

1.2 信号表

在终端,可通过kill -l查看所有的signal信号

取值 名称 解释 默认动作
1 SIGHUP 挂起  
2 SIGINT 中断  
3 SIGQUIT 退出  
4 SIGILL 非法指令  
5 SIGTRAP 断点或陷阱指令  
6 SIGABRT abort发出的信号  
7 SIGBUS 非法内存访问  
8 SIGFPE 浮点异常  
9 SIGKILL kill信号 不能被忽略、处理和阻塞
10 SIGUSR1 用户信号1  
11 SIGSEGV 无效内存访问  
12 SIGUSR2 用户信号2  
13 SIGPIPE 管道破损,没有读端的管道写数据  
14 SIGALRM alarm发出的信号  
15 SIGTERM 终止信号  
16 SIGSTKFLT 栈溢出  
17 SIGCHLD 子进程退出 默认忽略
18 SIGCONT 进程继续  
19 SIGSTOP 进程停止 不能被忽略、处理和阻塞
20 SIGTSTP 进程停止  
21 SIGTTIN 进程停止,后台进程从终端读数据时  
22 SIGTTOU 进程停止,后台进程想终端写数据时  
23 SIGURG I/O有紧急数据到达当前进程 默认忽略
24 SIGXCPU 进程的CPU时间片到期  
25 SIGXFSZ 文件大小的超出上限  
26 SIGVTALRM 虚拟时钟超时  
27 SIGPROF profile时钟超时  
28 SIGWINCH 窗口大小改变 默认忽略
29 SIGIO I/O相关  
30 SIGPWR 关机 默认忽略
31 SIGSYS 系统调用异常  

对于signal信号,绝大部分的默认处理都是终止进程或停止进程,或dump内核映像转储。 上述的31的信号为非实时信号,其他的信号32-64 都是实时信号。

二、信号产生

信号来源分为硬件类和软件类:

2.1 硬件方式

  • 用户输入:比如在终端上按下组合键ctrl+C,产生SIGINT信号;
  • 硬件异常:CPU检测到内存非法访问等异常,通知内核生成相应信号,并发送给发生事件的进程;

2.2 软件方式

通过系统调用,发送signal信号:kill(),raise(),sigqueue(),alarm(),setitimer(),abort()

  • kernel,使用 kill_proc_info()等
  • native,使用 kill() 或者raise()等
  • java,使用 Procees.sendSignal()等

三、信号注册和注销

3.1 注册

在进程task_struct结构体中有一个未决信号的成员变量 struct sigpending pending。每个信号在进程中注册都会把信号值加入到进程的未决信号集。

  • 非实时信号发送给进程时,如果该信息已经在进程中注册过,不会再次注册,故信号会丢失;
  • 实时信号发送给进程时,不管该信号是否在进程中注册过,都会再次注册。故信号不会丢失;

3.2 注销

  • 非实时信号:不可重复注册,最多只有一个sigqueue结构;当该结构被释放后,把该信号从进程未决信号集中删除,则信号注销完毕;
  • 实时信号:可重复注册,可能存在多个sigqueue结构;当该信号的所有sigqueue处理完毕后,把该信号从进程未决信号集中删除,则信号注销完毕;

四、信号处理

内核处理进程收到的signal是在当前进程的上下文,故进程必须是Running状态。当进程唤醒或者调度后获取CPU,则会从内核态转到用户态时检测是否有signal等待处理,处理完,进程会把相应的未决信号从链表中去掉。

4.1 处理时机

signal信号处理时机: 内核态 -> signal信号处理 -> 用户态:

  • 在内核态,signal信号不起作用;
  • 在用户态,signal所有未被屏蔽的信号都处理完毕;
  • 当屏蔽信号,取消屏蔽时,会在下一次内核转用户态的过程中执行;

4.2 处理方式

进程对信号的处理方式: 有3种

  • 默认 接收到信号后按默认的行为处理该信号。 这是多数应用采取的处理方式。
  • 自定义 用自定义的信号处理函数来执行特定的动作
  • 忽略 接收到信号后不做任何反应。

4.3 信号安装

进程处理某个信号前,需要先在进程中安装此信号。安装过程主要是建立信号值和进程对相应信息值的动作。

信号安装函数

  • signal():不支持信号传递信息,主要用于非实时信号安装;
  • sigaction():支持信号传递信息,可用于所有信号安装;

其中 sigaction结构体

  • sa_handler:信号处理函数
  • sa_mask:指定信号处理程序执行过程中需要阻塞的信号;
  • sa_flags:标示位
    • SA_RESTART:使被信号打断的syscall重新发起。
    • SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。
    • SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到SIGCHLD信号,这时子进程如果退出也不会成为僵 尸进程。
    • SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号。
    • SA_RESETHAND:信号处理之后重新设置为默认的处理方式。
    • SA_SIGINFO:使用sa_sigaction成员而不是sa_handler作为信号处理函数。

函数原型:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  • signum:要操作的signal信号。
  • act:设置对signal信号的新处理方式。
  • oldact:原来对信号的处理方式。
  • 返回值:0 表示成功,-1 表示有错误发生。

4.4 信号发送

  • kill():用于向进程或进程组发送信号;
  • sigqueue():只能向一个进程发送信号,不能像进程组发送信号;主要针对实时信号提出,与sigaction()组合使用,当然也支持非实时信号的发送;
  • alarm():用于调用进程指定时间后发出SIGALARM信号;
  • setitimer():设置定时器,计时达到后给进程发送SIGALRM信号,功能比alarm更强大;
  • abort():向进程发送SIGABORT信号,默认进程会异常退出。
  • raise():用于向进程自身发送信号;

4.5 信号相关函数

信号集操作函数

  • sigemptyset(sigset_t *set):信号集全部清0;
  • sigfillset(sigset_t *set): 信号集全部置1,则信号集包含linux支持的64种信号;
  • sigaddset(sigset_t *set, int signum):向信号集中加入signum信号;
  • sigdelset(sigset_t *set, int signum):向信号集中删除signum信号;
  • sigismember(const sigset_t *set, int signum):判定信号signum是否存在信号集中。

信号阻塞函数

  • sigprocmask(int how, const sigset_t *set, sigset_t *oldset)); 不同how参数,实现不同功能

    • SIG_BLOCK:将set指向信号集中的信号,添加到进程阻塞信号集;
    • SIG_UNBLOCK:将set指向信号集中的信号,从进程阻塞信号集删除;
    • SIG_SETMASK:将set指向信号集中的信号,设置成进程阻塞信号集;
  • sigpending(sigset_t *set)):获取已发送到进程,却被阻塞的所有信号;
  • sigsuspend(const sigset_t *mask)):用mask代替进程的原有掩码,并暂停进程执行,直到收到信号再恢复原有掩码并继续执行进程。

想更进一步了解关于信号,可查看 http://akaedu.github.io/book/ch33.html

Linux信号(signal)机制【转】的更多相关文章

  1. 非常好的一篇对linux信号(signal)的解析 (转载)【转】

    转自:https://blog.csdn.net/return_cc/article/details/78845346 Linux信号(signal) 机制分析 转载至:https://www.cnb ...

  2. Linux 信号signal处理函数

    转自:http://www.cnblogs.com/taobataoma/archive/2007/08/30/875662.html alarm(设置信号传送闹钟) 相关函数 signal,slee ...

  3. Linux 信号signal处理函数--转

    alarm(设置信号传送闹钟)相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...

  4. Linux 信号signal处理机制

    信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全 ...

  5. Linux信号signal处理机制

    信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分.         一.信号的基本概念 ...

  6. linux信号调用机制

    在Linux中,信号是进程间通讯的一种方式,它采用的是异步机制.当信号发送到某个进程中时,操作系统会中断该进程的正常流程,并进入相应的信号处理函数执行操作,完成后再回到中断的地方继续执行. 需要说明的 ...

  7. linux 信号signal和sigaction理解

    今天看到unp时发现之前对signal到理解实在浅显,今天拿来单独学习讨论下. signal,此函数相对简单一些,给定一个信号,给出信号处理函数则可,当然,函数简单,其功能也相对简单许多,简单给出个函 ...

  8. linux 信号与处理

    一.linux信号是什么 基本概念 信号是事件发生时对进程的通知机制,也就是所谓的软件中断.信号和硬件的中断类似,是软件层对中断机制的模拟,在多数情况下是无法预测信号产生的时间,所以软件层提供了一种处 ...

  9. Linux 信号:signal 与 sigaction

    0.Linux下查看支持的信号列表: france@Ubuntux64:~$ kill -l ) SIGHUP ) SIGINT ) SIGQUIT ) SIGILL ) SIGTRAP ) SIGA ...

随机推荐

  1. 注解Annotation实现原理与自定义注解例子

    什么是注解? 对于很多初次接触的开发者来说应该都有这个疑问?Annontation是Java5开始引入的新特征,中文名称叫注解.它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metada ...

  2. Daily Scrum - 11/13

    时间:3:00pm - 3:30pm 今天小组例会主要是任烁分享他对WP源码的code review,通过分析与讨论我们了解了背单词模块的主要类(主要是词和单词本),取词方式(调用数据库接口),算法( ...

  3. 团队作业一 庆祝"十五万的总冠军"成立

    很荣幸能够撰写我们团队的第一篇博客. 我们这些同学能组成一个新的团队真的很高兴,团队中的每一个人都有自己的优点的长处.希望在工作中我们能竭尽 所能,充分发挥我们的本事,让我们大家各自发挥自己的才能.. ...

  4. ElasticSearch 2 (28) - 信息聚合系列之高层概念

    ElasticSearch 2 (28) - 信息聚合系列之高层概念 摘要 和查询表达式(query DSL)一样,聚合也有一种可编辑的语法:可以根据我们的需要混合以及匹配使用独立的功能单元.这也就是 ...

  5. 使用Samba服务程序,让linux系统之间共享文件

    yum  install -y   cifs-utils mkdir  /database    创建挂载目录 在root家目录创建认证文件(依次为SMB用户名.SMB用户密码.SMB共享域)   v ...

  6. Alpha 冲刺六

    团队成员 051601135 岳冠宇 051604103 陈思孝 031602629 刘意晗 031602248 郑智文 031602234 王淇 会议照片 今天没有进行站立式会议,由于团队内有些细节 ...

  7. jdk命令行工具:jstat与jmap

    转自文章:http://blog.csdn.net/gzh0222/article/details/8538727 C:\Users\Administrator\Desktop>jstat -g ...

  8. 如何判断可见字符 Unicode

    一个Unicode字符串,如何判断其中都是可见字符? //根据国标 GB2312 的中文汉字及符号 区位码的范围判断 Function CheckIsGB2312(Char : WideChar) : ...

  9. [转帖]PG的简单备份恢复 找时间进行测试

    转帖PG的简单使用 https://blog.csdn.net/lk_db/article/details/77971634 一: 纯文件格式的脚本: 示例:1. 只导出postgres数据库的数据, ...

  10. mybatis之DAO层自动实现接口

    * 使用mybatis举例,使用DAO接口方式实现* 不需要针对接口去编写具体的实现类代码,编写映射XML文件,直接拿来使用即可.* 1.导入jar包:mybatis和mysql-connector* ...