信号捕获trap及其实例应用

1Linux支持的信号(标红部分为常用信号)

信号(Signal):信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相应的处理函数。进程可以忽略信号、捕捉信号和执行缺省操作。其中SIGKILLSIGSTOP两个信号不能忽略。

 

1.1Linux支持的信号列表

编号

信号名称

缺省动作

描述

1

SIGHUP

终止

终止进程,挂起

2

SIGINT

终止

键盘输入中断命令,一般是CTRL+C

3

SIGQUIT

CoreDump

键盘输入退出命令,一般是CTRL+\

4

SIGILL

CoreDump

非法指令

5

SIGTRAP

CoreDump

trap指令发出,一般调试用

6

SIGABRT

CoreDump

abort(3)发出的终止信号

7

SIGBUS

CoreDump

非法地址

8

SIGFPE

CoreDump

浮点数异常

9

SIGKILL

终止

立即停止进程,不能捕获,不能忽略

10

SIGUSR1

终止

用户自定义信号1,像Nginx就支持USR1信号,用于重载配置,重新打开日志

11

SIGSEGV

CoreDump

无效内存引用

12

SIGUSR2

终止

用户自定义信号2

13

SIGPIPE

终止

管道不能访问

14

SIGALRM

终止

时钟信号,alrm(2)发出的终止信号

15

SIGTERM

终止

终止信号,进程会先关闭正在运行的任务或打开的文件再终止,有时间进程在有运行的任务而忽略此信号。不能捕捉

16

SIGSTKFLT

终止

处理器栈错误

17

SIGCHLD

可忽略

子进程结束时,父进程收到的信号

18

SIGCONT

可忽略

让终止的进程继续执行

19

SIGSTOP

停止

停止进程,不能忽略,不能捕获

20

SIGSTP

停止

停止进程,一般是CTRL+Z

21

SIGTTIN

停止

后台进程从终端读数据

22

SIGTTOU

停止

后台进程从终端写数据

23

SIGURG

可忽略

紧急数组是否到达socket

24

SIGXCPU

CoreDump

超出CPU占用资源限制

25

SIGXFSZ

CoreDump

超出文件大小资源限制

26

SIGVTALRM

终止

虚拟时钟信号,类似于SIGALRM,但计算的是进程占用的时间

27

SIGPROF

终止

类似与SIGALRM,但计算的是进程占用CPU的时间

28

SIGWINCH

可忽略

窗口大小改变发出的信号

29

SIGIO

终止

文件描述符准备就绪,可以输入/输出操作了

30

SIGPWR

终止

电源失败

31

SIGSYS

CoreDump

非法系统调用

注意:9 信号,捕获不住,也无法忽略。

 

1.2Linux支持的两种信号类型

1、标准信号,编号1-31,称为非可靠信号(非实时),不支持队列,信号可能会丢失,比如发送多次相同的信号,进程只能收到一次,如果第一个信号没有处理完,第二个信号将会丢弃。

 

2、扩展信号,编号32-64,称为可靠信号(实时),支持队列,发多少次进程就可以收到多少次。

 

1.3、发送信号的两种情况

第一种是内核检测到系统事件,比如键盘输入CTRL+C会发送SIGINT信号。另一种是通过系统调用kill命令来向一个进程发送信号。

2trap命令语法格式

语法

含义

trap ' 触发指令' 信号

自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作

trap '' 信号

忽略信号的操作

trap '-' 信号

恢复原信号的操作

trap -p

列出自定义信号操作

信号可以3种表达方法:信号的数字2、全名SIGINT、缩写INT

3trap实例应用

1:打印0-9ctrl+c不能终止

#!/bin/bash

trap 'echo press ctrl+c' 2

for ((i=0;i<10;i++));do

        sleep 1

        echo $i

done

分析:i=0,当i<10,每休眠1秒,i+1,捕获2信号(也就是键盘ctrl+c),并把echo后面的内容输入到终端屏幕。

2:打印0-5ctrl+c不能终止,5之后恢复,能终止

#!/bin/bash

trap '' 2

trap -p

for ((i=0;i<5;i++));do

        sleep 1

        echo $i

done

trap '-' SIGINT

for ((i=5;i<20;i++));do

        sleep 1

        echo $i

done

分析:i=0,当i<5,每休眠1秒,i+1,捕获2信号;i>5时,解除捕获2信号。