首页 > 技术文章 > python 信号处理

newzol 2018-03-30 18:16 原文

linux开发中,通常会在进程中设置专门的信号处理方法,比如经常使用的CTRL+C,KILL等信号.如果你熟悉liunx编程,那么python等信号处理方法对你来说就很简单,下面的内容将主要介绍python 中singal包的使用.

一、signal使用实例
import signal, os

def handler(signum, frame):
    print 'Signal handler called with signal', signum
    raise IOError("Couldn't open device!")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This open() may hang indefinitely
fd = os.open('/dev/ttyS0', os.O_RDWR)

signal.alarm(0)          # Disable the alarm

这段代码是python官网提供的实例代码,现在还不明白没关系,接着向下看.

二、signal定义和使用
signal包中,提供了对信号处理接口和定义的各种信号量.
sihnal.signal(signalnumhandler)接口可以向系统注册处理的信号和要处理的操作, signalnum为要处理的信号,可以为SIGNNT、SIGNQUIT等信号,hander为捕获到信号后的处理方法,可以使用signal中的默认处理标志(SIG_DFL)或者忽略(SIG_IGN).也可以自定义操作.实例如下:
#!/usr/bin/python
#coding:utf-8
import signal,os
def signal_fun(signum,frame):
    print 'recv signal:%d' % signum
    
if __name__ == '__main__':
    signal.signal(signal.SIGINT, signal_fun)
    signal.pause()

signal_fun接口就是接收到信号后自定义的处理方法,signal.pause()调用后,会使进程一直阻塞,直到接收到处理信号,处理完成后退出.

上面的脚本使用python sign.py运行后,会一直阻塞在signal.pause(),当输入ctrl+c后,脚本会接收到信号,然后打印信号类型,并结束运行,实际的编码过程中可以在主程序的main函数中预先注册需要处理的的信号.并使用默认的处理逻辑,满足实际的需要.使用的场景主要是:
1、设置标志让进程退出.进程在循环处理任务时不能够使用kill-9.这样会破坏进程的正常处理流程,使用kill时要等任务处理完才会退出,有时候等待的时间会比较久,因此,实际使用时,可以在接收信号后,设置进程退出标示,等当前事务处理完,判断退出标示,然后正常退出进程.
2、忽略某些信号,linux信号处理机制可以帮助我们做很多事情,但是遇到不想处理的信号时需要将其过滤,只处理需要使用的信号
 
三、定时发送信号
回到第一个问题,看如下案例:
运行脚本,脚本调用signal.alarm(5)5秒后给自身发送一个alarm信号,然后进程被阻塞,5秒后,进程收到自身给自身发送的信号,处理退出.alarm参数为0时,默认失效.
 
四、总结

signal.SIG* 各种信号表示

signal.signal(signum,frame) 注册信号

signal.pause() 堵塞信号

signal.alarm() 发送告警信号

推荐阅读