Linux信号(signal)机制【转】
转自: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)机制【转】的更多相关文章
- 非常好的一篇对linux信号(signal)的解析 (转载)【转】
转自:https://blog.csdn.net/return_cc/article/details/78845346 Linux信号(signal) 机制分析 转载至:https://www.cnb ...
- Linux 信号signal处理函数
转自:http://www.cnblogs.com/taobataoma/archive/2007/08/30/875662.html alarm(设置信号传送闹钟) 相关函数 signal,slee ...
- Linux 信号signal处理函数--转
alarm(设置信号传送闹钟)相关函数 signal,sleep 表头文件 #include<unistd.h> 定义函数 unsigned int alarm(unsigned int ...
- Linux 信号signal处理机制
信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全 ...
- Linux信号signal处理机制
信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 ...
- linux信号调用机制
在Linux中,信号是进程间通讯的一种方式,它采用的是异步机制.当信号发送到某个进程中时,操作系统会中断该进程的正常流程,并进入相应的信号处理函数执行操作,完成后再回到中断的地方继续执行. 需要说明的 ...
- linux 信号signal和sigaction理解
今天看到unp时发现之前对signal到理解实在浅显,今天拿来单独学习讨论下. signal,此函数相对简单一些,给定一个信号,给出信号处理函数则可,当然,函数简单,其功能也相对简单许多,简单给出个函 ...
- linux 信号与处理
一.linux信号是什么 基本概念 信号是事件发生时对进程的通知机制,也就是所谓的软件中断.信号和硬件的中断类似,是软件层对中断机制的模拟,在多数情况下是无法预测信号产生的时间,所以软件层提供了一种处 ...
- Linux 信号:signal 与 sigaction
0.Linux下查看支持的信号列表: france@Ubuntux64:~$ kill -l ) SIGHUP ) SIGINT ) SIGQUIT ) SIGILL ) SIGTRAP ) SIGA ...
随机推荐
- 2017-2018 第一学期201623班《程序设计与数据结构》-第9&10周作业问题总结
一.作业内容 第8周作业 http://www.cnblogs.com/rocedu/p/7484252.html#WEEK08 第9周作业 http://www.cnblogs.com/rocedu ...
- linux 常用命令-变量命令
想要的结果,有时候我们想使用上一句命令的执行结果,当然可以通过鼠标去复制粘贴,但是这样既不库又效率低,所以想能不能通过快捷键获取上一句命令的值执行结果呢,答案是不能,后来想如果能把执行结果存入变量那不 ...
- [转帖] 学习 Linux 大页的内存知识
一.在解释什么情况下需要开启大页和为啥需要开启大页前先了解下Linux下页的相关的知识:以下的内容是基于32位的系统,4K的内存页大小做出的计算1)目录表,用来存放页表的位置,共包含1024个目录en ...
- TP3.2加载外部PHPexcel类,实现导入和导出
TP3.2加载外部PHPexcel类,实现导入和导出 导入: 1.将下载好的PHPexcel文件放到libray/Org/Uti/文件夹下,将PHPEXCEL.PHP改为PHPEXCEL.class. ...
- 题解 P5239 【回忆京都】
你们这些写题解的,就不能把话说清楚嘛!(吐槽1) 你们这些出题的,就不能多出点东方嘛!(吐槽2) 你们这些做题的,就不来写一篇详细一点的题解嘛!(吐槽3) 以上均是个人吐槽,纯属吐槽,不带任何针对性和 ...
- photoshop cc 2018破解补丁(pscc2018注册机) 附使用方法
1.下载破解程序 破解文件自行到 http://www.ddooo.com/softdown/109954.htm 下载 博主可以到本博客的文件-->pscc2018zcj_109954.ra ...
- Spring点滴九:Spring bean的延迟初始化
Spring bean延迟初始化: 官网API: By default, ApplicationContext implementations eagerly create and configure ...
- 【BZOJ2054】疯狂的馒头(并查集,线段树)
[BZOJ2054]疯狂的馒头(并查集,线段树) 题面 BZOJ 然而权限题,随便找个离线题库看看题吧. 题解 线段树就是个暴力,如果数据可以构造就能卡掉,然而不能构造,要不然复杂度瓶颈成为了读入了. ...
- C/C++ exception类
#include <iostream> #include <iomanip> #include <string> #include <sstream> ...
- java基础基础总结----- RunTime