Python 内建包-signal

1. wiki

全称为软中断信号,作用是通知进程发生了异步事件。进程之间可以调用系统来传递信号,本身内核也可以发送信号给进程, 告诉该进程发生了某个事件。

信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。

1.1. 信号类型

不同系统中同一个数值对应的信号类型不一样,信号的数值越小,优先级越高。

Linux 系统有 2 大类信号:

  • POSIX标准的规则信号(regular signal 1-31编号)
  • 实时信号(real-time signal 32-63)

linux 使用的规则信号可以参看最后附录

1.2. 信号处理

接收信号的进程对不同的信号有 3 种处理方法:

  • 指定处理函数
  • 忽略
  • 根据系统默认值处理,大部分信号的默认处理是终止进程

2. 使用

一般使用方法是:

  1. 自定义信号处理函数,来处理接受到不同信号时采用什么函数,并向进程发送信号
  2. 处理信号,调用 signal.signal(signalnum, handler) 将信号和相应函数传入

2.1. 定义信号处理函数

与一般的函数无差别,但需要再接收信号后,向进程发送相应信号,比如退出(signal.SIGQUIT)、中断(signal.SIGTERM)等。常用的发送信号函数有:

  • signal 包 : signal.alarm(time) ,在 time 秒后向进程自身发送 SIGALRM 信号
  • subprocess 包 : child_process.send_signal(sid)
  • os
    • os.kill(pid, sid) ,类似 kill 命令
    • os.killpg(pgid, sid) ,类似 kill 命令

2.2. 处理信号

在接收到 signalnum 信号时,调用 handler 函数

1
signal.signal(signalnum, handler)
  • signalnum : 具体的信号量,可以是数字值(如 2 ),也可以是符号类型(如 signal.SIGINT)
  • handler 该信号的处理函数,主要对应上面说的 3 种处理办法
    • handler 为一个函数名时,进程采取函数中定义的操作
    • handlersignal.SIG_IGN 时,信号被无视(ignore)
    • handlersingal.SIG_DFL,进程采取默认操作(default)

2.3. 其他函数

  • signal.pause() : 阻塞进程执行以等待信号,简单来说当接收到信号后使进程停止
  • signal.getsignal(signalnum) : 获取当前程序注册 signalnum 信号量的处理函数

3. 举例

定义信号处理函数 suicide(),使用 register_signal() 函数来处理相应信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def suicide(signum, e):
global child_process
print >> sys.stderr, "[Error] DataX receive unexpected signal %d, starts to suicide." % (signum)

if child_process:
child_process.send_signal(signal.SIGQUIT)
time.sleep(1)
child_process.kill()
print >> sys.stderr, "DataX Process was killed ! you did ?"
sys.exit(RET_STATE["KILL"])

def register_signal():
global child_process
signal.signal(signal.SIGINT, suicide)
signal.signal(signal.SIGQUIT, suicide)
signal.signal(signal.SIGTERM, suicide)

if __name__ == "__main__":
startCommand = "ls -la"
child_process = subprocess.Popen(startCommand, shell=True)
register_signal()

附录

1. 规则信号

信号编号 名称 默认动作 说明
1 SIGHUP 终止 终止控制终端或进程
2 SIGINT 终止 由键盘引起的终端(Ctrl-c)
3 SIGQUIT dump 控制终端发送给进程的信号, 键盘产生的退出(Ctrl-),
4 GIGILL dusmp 非法指令引起
5 SIGTRAP dump debug中断
6 SIGABRT/SIGIOT dump 异常中止
7 SIGBUS/SIGEMT dump 总线异常/EMT指令
8 SIGFPE dump 浮点运算溢出
9 SIGKILL 终止 强制杀死进程(大招, 进程不可捕获)
10 SIGUSR1 终止 用户信号, 进程可自定义用途
11 SIGSEGV dump 非法内存地址引起
12 SIGUSR2 终止 用户信号, 进程可自定义用途
13 SIGPIPE 终止 向某个没有读取的管道中写入数据
14 SIGALRM 终止 时钟中断(闹钟)
15 SIGTERM 终止 进程终止(进程可捕获)
16 SIGSTKFLT 终止 协处理器栈错误
17 SIGCHLD 忽略 子进程退出或中断
18 SIGCONT 继续 如进程停止状态则开始运行
19 SIGSTOP 停止 停止进程运行
20 SIGSTP 停止 键盘产生的停止
21 SIGTTIN 停止 后台进程请求输入
22 SIGTTOU 停止 后台进程请求输出
23 SIGURG 忽略 socket发送紧急情况
24 SIGXCPU dump CPU时间限制被打破
25 SIGXFSZ dump 文件大小限制被打破
26 SIGVTALRM 终止 虚拟定时时钟
27 SIGPROF 终止 profile timer clock
28 SIGWINCH 忽略 窗口尺寸调整
29 SIGIO/SIGPOLL 终止 I/O可用
30 SIGPWR 终止 电源异常
31 SIGSYS/SYSUNUSED dump 系统调用异常