Linux信号机制与信号处理

信号(signal)是Linux进程间通信的一种机制,全称为软中断信号,也被称为软中断。信号本质上是在软件层次上对硬件中断机制的一种模拟。

与其他进程间通信方式(例如管道、共享内存等)相比,信号所能传递的信息比较粗糙,只是一个整数。但正是由于传递的信息量少,信号也便于管理和使用,可以用于系统管理相关的任务,例如通知进程终结、中止或者恢复等。

每种信号用一个整型常量宏表示,以SIG开头,比如SIGCHLD、SIGINT等,它们在系统头文件中定义。

信号由内核(kernel)管理,产生方式多种多样:

可以由内核自身产生,比如出现硬件错误、内存读取错误,分母为0的除法等,内核需要通知相应进程。

也可以由其他进程产生并发送给内核,再由内核传递给目标进程。

信号传递的过程:

内核中针对每一个进程都有一个表来保存信号。

当内核需要将信号传递给某个进程时,就在该进程对应的表中写入信号,这样就生成了信号。

当该进程由用户态陷入内核态,再次切换到用户态之前,会查看表中的信号。如果有信号,进程就会首先执行信号对应的操作,此时叫做执行信号。

从生成信号到将信号传递给对应进程这段时间,信号处于等待状态。

我们可以编写代码,让进程阻塞(block)某些信号,也就是让这些信号始终处于等待的状态,直到进程取消阻塞(unblock)或者忽略信号。

信号种类

下表列出了一些常见信号:

信号名称数字表示说明

SIGHUP 1 终端挂起或控制进程终止。当用户退出Shell时,由该进程启动的所有进程都会收到这个信号,默认动作为终止进程。

SIGINT 2 键盘中断。当用户按下组合键时,用户终端向正在运行中的由该终端启动的程序发出此信号。默认动作为终止进程。

SIGQUIT 3 键盘退出键被按下。当用户按下或组合键时,用户终端向正在运行中的由该终端启动的程序发出此信号。默认动作为退出程序。

SIGFPE 8 发生致命的运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为0等所有的算法错误。默认动作为终止进程并产生core文件。

SIGKILL 9 无条件终止进程。进程接收到该信号会立即终止,不进行清理和暂存工作。该信号不能被忽略、处理和阻塞,它向系统管理员提供了可以杀死任何进程的方法。

SIGALRM 14 定时器超时,默认动作为终止进程。

SIGTERM 15 程序结束信号,可以由 kill 命令产生。与SIGKILL不同的是,SIGTERM 信号可以被阻塞和终止,以便程序在退出前可以保存工作或清理临时文件等。

通过 kill -l 命令可以查看系统支持的所有信号:

$ kill -l

1) SIGHUP      2) SIGINT      3) SIGQUIT      4) SIGILL

5) SIGTRAP      6) SIGABRT      7) SIGBUS      8) SIGFPE

9) SIGKILL    10) SIGUSR1    11) SIGSEGV    12) SIGUSR2

13) SIGPIPE    14) SIGALRM    15) SIGTERM    16) SIGSTKFLT

17) SIGCHLD    18) SIGCONT    19) SIGSTOP    20) SIGTSTP

21) SIGTTIN    22) SIGTTOU    23) SIGURG      24) SIGXCPU

25) SIGXFSZ    26) SIGVTALRM  27) SIGPROF    28) SIGWINCH

29) SIGIO      30) SIGPWR      31) SIGSYS      34) SIGRTMIN

35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4

39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10

55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6

59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX

上面仅是一个演示,不同的Linux发行版支持的信号可能不同。

每种信号都会有一个默认动作。默认动作就是脚本或程序接收到该信号所做出的默认操作。常见的默认动作有终止进程、退出程序、忽略信号、重启暂停的进程等,上表中也对部分默认动作进行了说明。

发送信号

有多种方式可以向程序或脚本发送信号,例如按下组合键会发送SIGINT信号,终止当前进程。

还可以通过 kill 命令发送信号,语法为:

$ kill -signal pid

signal为要发送的信号,可以是信号名称或数字;pid为接收信号的进程ID。例如:

$ kill -1 1001

将SIGHUP信号发送给进程ID为1001的程序,程序会终止执行。

又如,强制杀死ID为1001的进程:

$ kill -9 1001

捕获信号

通常情况下,直接终止进程并不是我们所希望的。例如,按下,进程被立即终止,不会清理创建的临时文件,带来系统垃圾,也不会保存正在进行的工作,导致需要重做。

可以通过编程来捕获这些信号,当终止信号出现时,可以先进行清场和保存处理,再退出程序。

用户程序可以通过C/C++等代码捕获信号,这将在Linux C编程中进行讲解,这里仅介绍如果通过Linux命令捕获信号。

通过 trap 命令就可以捕获信号,语法为:

$ trap commands signals

commands为Linux系统命令或用户自定义命令;signals为要捕获的信号,可以为信号名称或数字。

捕获到信号后,可以有三种处理:

执行一段脚本来做一些处理工作,例如清理临时文件;

接受(恢复)信号的默认操作;

忽略当前信号。

1) 清理临时文件

脚本捕获到终止信号后一个常见的动作就是清理临时文件。例如:

$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2

当用户按下后,脚本先清理临时文件 work1

和dataout

再退出。

注意:exit 命令是必须的,否则脚本捕获到信号后会继续执行而不是退出。

修改上面的脚本,使接收到 SIGHUP 时进行同样的操作:

$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2

几点注意:

如果执行多个命令,需要将命令用引号包围;

只有脚本执行到 trap 命令时才会捕获信号;

再次接收到信号时还会执行同样的操作。

上面的脚本,执行到 trap 命令时就会替换 WORKDIR 和 $$ 的值。如果希望接收到 SIGHUP 或 SIGINT 信号时再替换其值,那么可以将命令放在单引号内,例如:

$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2

2) 忽略信号

如果 trap 命令的 commands 为空,将会忽略接收到的信号,即不做任何处理,也不执行默认动作。例如:

$ trap '' 2

也可以同时忽略多个信号:

$ trap '' 1 2 3 15

注意:必须被引号包围,不能写成下面的形式:

$ trap  2

3) 恢复默认动作

如果希望改变信号的默认动作后再次恢复默认动作,那么省略 trap 命令的 commands 即可,例如:

$ trap 1 2

将恢复SIGHUP 和 SIGINT 信号的默认动作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容