Python 信号处理 signal 模块
Table of Contents
- 1. signal模块简介
- 1.1. signal简单示例
- 1.2. signal说明
- 1.2.1. 基本的信号名
- 1.2.2. 常用信号处理函数
- 2. signal使用示例
- 2.1. 示例1
- 2.2. 示例2
- 3. 参考资料
signal模块简介
最近在看Linux signal
相关内容,signal可以被用来进程间通信和异步处理。Python标准库提供了signal包可以用来处理信号相关。这里讨论的是Unix系统中Python的signal模块。
signal简单示例
官方文档上有这样的示例:
import signal, os # 定义一个信号处理函数,该函数打印收到的信号,然后raise IOError def handler(signum, frame): print 'Signal handler called with signal', signum raise IOError("Couldn't open device!") # 对SIGALRM(终止)设置处理的handler, 然后设置定时器,5秒后触发SIGALRM信号 signal.signal(signal.SIGALRM, handler) signal.alarm(5) # This open() may hang indefinitely fd = os.open('/dev/ttyS0', os.O_RDWR) signal.alarm(0) # 关闭定时器
该示例实现的功能是,为了防止打开一个文件出错或者其他异常一直处于等待的状态,设定一个定时器,5秒后触发IOError。如果5s内正常打开文件,则清除定时器。
signal说明
基本的信号名
import signal signal.SIGABORT signal.SIGHUP # 连接挂断 signal.SIGILL # 非法指令 signal.SIGINT # 连接中断 signal.SIGKILL # 终止进程(此信号不能被捕获或忽略) signal.SIGQUIT # 终端退出 signal.SIGTERM # 终止 signal.SIGALRM # 超时警告 signal.SIGCONT # 继续执行暂停进程 等等...
常用信号处理函数
- signal.signal(signalnum, handler)
设置信号处理的函数 - signal.alarm(time)
设置发送SIGALRM信号的定时器 - os.kill
这个不属于signal模块,但其可以使用给某一进程发送信号
signal使用示例
示例1
# From project httpscreenshot-master, under directory , in source file httpscreenshot.py. def timeoutFn(func, args=(), kwargs={}, timeout_duration=1, default=None): import signal class TimeoutError(Exception): pass def handler(signum, frame): raise TimeoutError() # set the timeout handler signal.signal(signal.SIGALRM, handler) signal.alarm(timeout_duration) try: result = func(*args, **kwargs) except TimeoutError as exc: result = default finally: signal.alarm(0) signal.signal(signal.SIGALRM, signal.SIG_DFL) return result
上面这个示例实现了设置函数执行超时返回默认结果的功能。先是设置了一个超时处理函数,在函数中抛出自定义的抛出异常。在执行函数前设置了 signal.alarm
,当超出时间后触发抛出异常 SIGALRM
, 然后捕获这个异常设置默认值,最后做下清理工作将定时器取消,并且将对 SIGALRM
的处理设为默认。
示例2
这个示例来源于这里。 需求是动态加载python导入的模块,也就是说,当导入的模块代码更新时,希望可以立即更新引用的代码。示例如下:
# lib.py def scrape_me_bro(): print "Scraping is fun" #scrape.py import time import signal import lib def scrape(): # Assume we are hitting Streaming API # and doing something buzzwordy with it while True: lib.scrape_me_bro() time.sleep(2) def reload_libs(signum, frame): print "Received Signal: %s at frame: %s" % (signum, frame) print "Excuting a Lib Reload" reload(lib) # Register reload_libs to be called on restart signal.signal(signal.SIGHUP, reload_libs) # Main scrape()
当运行scrape.py时,程序会每个两秒调用一次lib.py中的 scrape_me_bro()
方法,这时候如果lib.py里的方法变化了,向运行scrape.py的进程发送 SIGHUP
信号,那么它会重新加载lib.py,这样会接着循环执行修改后的 scrape_me_bro()
方法。
参考资料
- 《Beginning Linux Programming》
- https://docs.python.org/2/library/signal.html
- http://engineerwithoutacause.com/easy-signal-handling-for-python-daemons.html
- http://www.programcreek.com/python/example/1220/signal.SIGALRM
相关推荐
pointfish 2020-07-18
PythonGCS 2019-01-09
wangrui0 2019-12-26
sunnyJam 2019-10-20
岳英豪 2019-09-07
pbyanglove 2011-07-14
郭枫 2019-07-01
rually 2019-06-25
PpikachuP 2019-06-21
星际之旅 2019-06-20
aifeng 2016-12-02
鹰之翔 2012-02-18
manmanoy 2018-01-25
shipinsky 2017-01-16
hanjinixng00 2017-01-16
taianxiaojia 2015-01-11
gnulinux 2015-11-13
mengyun00 2019-04-20