视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Python信号处理signal模块
2020-11-27 14:27:49 责编:小采
文档


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() 方法。

下载本文
显示全文
专题