最近在看Linux signal
相关内容,signal能够被用来进程间通讯和异步处理。Python标准库提供了signal包能够用来处理信号相关。这里讨论的是Unix系统中Python的signal模块。html
官方文档上有这样的示例:python
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内正常打开文件,则清除定时器。api
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.killrest
这个不属于signal模块,但其能够使用给某一进程发送信号
# 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
的处理设为默认。code
这个示例来源于这里。 需求是动态加载python导入的模块,也就是说,当导入的模块代码更新时,但愿能够当即更新引用的代码。示例以下:htm
# 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()
方法。blog
《Beginning Linux Programming》进程