linux 信号与处理
一、linux信号是什么
- 基本概念
信号是事件发生时对进程的通知机制,也就是所谓的软件中断。信号和硬件的中断类似,是软件层对中断机制的模拟,在多数情况下是无法预测信号产生的时间,所以软件层提供了一种处理异步事件的方法。
二、 信号来源
信号的来源分为硬件来源和软件来源。
- 硬件来源:
- 硬件发生异常,即硬件检测到错误条件并通知内核,随即再由内核发送相应的信号给相关进程,如除数为0、无效的内存引用等。
- 用户按终端键,引起终端产生的信号(比如Ctrl + C键产生SIGINT)。
- 软件来源:
- 用户通过指令杀死,如kill指令。
- 发生软件事件, 如程序执行raise, alarm、setitimer、sigqueue等函数。
三、 信号处理
信号通常是发送给对应的进程,当信号到达后,该进程需要做出相应的处理措施,通常进程会视具体信号执行相应的操作,有三种操作方式。
- 忽略信号:
信号到达后、直接忽略,就好像是没有出该信号,信号对该进程不会产生任何影响。事实上,大多数信号都可以使用这种方式进行处理,但有两种信号却决不能被忽略,分别是SIGKILL 和 SIGSTOP。 - 捕获信号:
当信号到达进程后,执行signal()绑定好的信号处理函数。 - 执行系统默认操作:
进程不对该信号事件作出处理,而是交由系统进行处理,每一种信号都会有其对应的系统默认的处理方式。
四、常见信号
在linux系统中通过kill -l命令可以查看到相应的信号。信号编号是从 1 开始,不存在编号为 0 的信号,事实上 kill()函数对信号编号 0 有着特殊的应用。

注意:括号" ) "前面的数字对应该信号的编号,编号 1~31 所对应的是不可靠信号,编号 34~64 对应的是可靠信号,从图中可知,可靠信号并没有一个具体对应的名字,而是使用了 SIGRTMIN+N 或 SIGRTMAXN 的方式来表示。其中32和33空缺。
不可靠信号表
| 值 | 名称 | 解释 | 默认动作 |
|---|---|---|---|
| 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()
"signal.h"信号处理库提供了signal函数,用来捕获突发事件。以下是 signal() 函数的语法ads。
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- signum:可使用信号名(宏)或信号的数字编号,建议使用信号名。
- handler:参数 handler 既可以设置为用户自定义的函数,也可以设置为 SIG_IGN 或 SIG_DFL,SIG_IGN 表示此进程需要忽略该信号,SIG_DFL 则表示设置为系统默认操作。
- raise()
有时进程需要向自身发送信号,raise()函数可用于实现这一要求.
int raise(int sig);
- sig:需要发送的信号。
- sigaction()
除了signal()之外,sigaction()系统调用是设置信号处理方式的另一选择,虽然 signal()函数简单好用,而 sigaction()更为复杂,但作为回报,sigaction()也更具灵活性以及移植性。
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
- signum:需要设置的信号,除了 SIGKILL 信号和 SIGSTOP 信号之外的任何信号。
- act:参数 act 不为 NULL,则表示需要为信号设置新的处理方式;如果参数 act 为 NULL,则表示无需改变信号当前的处理方式
- oldact:参数oldact 不为 NULL,则会将信号之前的处理方式等信息通过参数 oldact 返回出来;如果无意获取此类信息,那么可将该参数设置为 NULL。
- 返回值:成功返回 0;失败将返回-1,并设置 errno。
struct sigaction 结构体
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
- sa_handler:指定信号处理函数,与 signal()函数的 handler 参数相同。
- sa_sigaction:也用于指定信号处理函数,这是一个替代的信号处理函数。
- sa_mask:参数 sa_mask 定义了一组信号。
- sa_restorer:该成员已过时,不要再使用了。
- sa_flags:参数 sa_flags 指定了一组标志,这些标志用于控制信号的处理过程。
- kill()
kill()系统调用可将信号发送给指定的进程或进程组中的每一个进程。
int kill(pid_t pid, int sig);
- pid:参数 pid 为正数的情况下,用于指定接收此信号的进程 pid。
- sig:参数 sig 指定需要发送的信号,也可设置为 0,如果参数 sig 设置为 0 则表示不发送信号,但任执行错误检查,这通常可用于检查参数 pid 指定的进程是否存在。
- 返回值:成功返回 0;失败将返回-1,并设置 errno。
- alarm()
使用 alarm()函数可以设置一个定时器(闹钟),当定时器定时时间到时,内核会向进程发送 SIGALRM信号。
unsigned int alarm(unsigned int seconds);
- seconds:设置定时时间,以秒为单位;如果参数 seconds 等于 0,则表示取消之前设置的 alarm 闹钟。
- 返回值:如果在调用 alarm()时,之前已经为该进程设置了 alarm 闹钟还没有超时,则该闹钟的剩余值作为本次 alarm()函数调用的返回值,之前设置的闹钟则被新的替代;否则返回 0。
- pause()
pause()系统调用可以使得进程暂停运行、进入休眠状态,直到进程捕获到一个信号为止,只有执行了信号处理函数并从其返回时,pause()才返回,在这种情况下,pause()返回-1,并且将 errno 设置为EINTR。
int pause(void);
- 使用案例
demo1
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void signal_handler(int signum)
{
printf("Interrupt signal (%d) received. \n", signum);
switch(signum){
case SIGINT:
printf("ctrl + c \n");
exit(signum);
break;
case SIGQUIT:
printf("ctrl + \\ \n");
exit(signum);
}
}
int main(int argc, char *argv[]) {
int i = 0;
//注册信号与信号处理程序
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
while(1)
{
printf("Going to sleep....\n");
if (i > 5){
raise( SIGINT);
}
sleep(1);
i++;
}
return 0;
}
参考文献
Linux信号(signal)机制:http://gityuan.com/2015/12/20/signal/
linux 信号及处理过程详解:https://blog.csdn.net/u010765526/article/details/80085895
linux kill信号详解:https://www.cnblogs.com/gcb-1991/p/6922694.html
《正点原子应用编程指南》
linux 信号与处理的更多相关文章
- Linux信号类型说明
说明 在Linux系统开发中经常要使用到信号来实现异步通知机制.而在Linux系统中信号有很多种,也不用全部记住,学习几种常见的信号,学会使用即可:当然也要知道用哪种方式能够发送这样的信号. 查看li ...
- Linux信号基础
Linux信号基础 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux进程基础一文中已经提到,Linux以进程为单位来 ...
- Linux信号(signal) 机制分析
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
- Linux信号实践(2) --信号分类
信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号 ...
- 非常好的一篇对linux信号(signal)的解析 (转载)【转】
转自:https://blog.csdn.net/return_cc/article/details/78845346 Linux信号(signal) 机制分析 转载至:https://www.cnb ...
- Linux 信号:signal 与 sigaction
0.Linux下查看支持的信号列表: france@Ubuntux64:~$ kill -l ) SIGHUP ) SIGINT ) SIGQUIT ) SIGILL ) SIGTRAP ) SIGA ...
- Linux信号机制
Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...
- python学习笔记——多进程间通信——Linux信号基础
1 信号的基本描述 Signal信号(其全程为软中断信号)是Linux系统编程中非常重要的概念,信号是异步进程中通信的一种方式. 作用是通知进程发生了异步事件.进程之间可以调用系统来传递信号, 本身内 ...
- linux信号Linux下Signal信号太详细了,终于找到了
linux信号Linux下Signal信号太详细了,终于找到了 http://www.cppblog.com/sleepwom/archive/2010/12/27/137564.html
随机推荐
- 战胜了所有对手,却输给了时代。MVVM--jQuery永远的痛。
前言 第二次浏览器战争中,随着以 Firefox 和 Opera 为首的 W3C 阵营与 IE 对抗程度的加剧,浏览器碎片化问题越来越严重,不同的浏览器执行不同的标准,对于开发人员来说这是一个恶梦.为 ...
- ASP截取字符 截取字符之间的字符
ASP截取字符:MID函数Mid(变量或字串符,开始字节, 结尾字节(可不填)) InStrRev(变量, "字串符") 最后出现位置InStr(变量, "字串符&qu ...
- 证明n个正数的算术平均数不小于它们的几何平均数
- centos7 权限更改,所属用户及用户组更改
2021-08-03 # 查看文件的权限 ll 第一个字符, "-" 表示是文件, "d" 表示是目录(directory) 后面 9 个字符每 3 个字符又作 ...
- 日常shell练习
2021-07-19 1.echo的使用 1.1 echo -n 表示不换行输出 # echo输出会自动换行,换行输出两个1 echo 1 echo 1 # 不换行输出,不换行输出两个1 echo - ...
- tomcat漏洞总结
描述 Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun 和其他一些公司及个人共同开发而成.由 ...
- java IO操作,看完你应该就清晰了。
前言: java中IO里的一些知识对于一个java新手来说,是比较难理解的.因为里面存在一些很绕的概念,比如: 1.到底是读入写出,还是读出写入: 2.我要将一个文件的内容拷贝到另一个文件是先用Inp ...
- NOIP模拟50
过分的神圣,往往比恶魔更加恶质. 前言 最大的一个收获就是不要动不动就码线段树,一定要审清楚题目之后再码!! T1 一开始理解错题了,以为答案是就是 \(\dfrac{\operatorname{le ...
- WEB安全性测试之文件上传漏洞
1.漏洞描述:文件上传漏洞,是指可以利用WEB上传一些特定的文件包含特定代码如(<?php phpnfo;?> 可以用于读取服务器配置信息.上传成功后可以点击) 上传漏洞是指用户上传了一个 ...
- Android Studio找不到设备,解决adb占用问题的方法
使用as连接真机时,找不到设备,发现 D:\Android\Sdk\platform-tools\adb.exe start-server' failed -- run manually if nec ...