signal
signal — Set handlers for asynchronous events
该模块提供了在Python中使用信号处理程序的机制。处理信号及其处理程序的一些通用规则:
- 一旦设置了特定信号的处理程序,直到它被显式重置(Python模拟BSD样式接口,而不管底层实现如何)时,它仍保持安装状态,除了底层实现之后的处理程序以外
SIGCHLD
。
- 暂时无法从关键部分“暂时”阻止信号(因为这不受所有Unix版本的支持)。
- 尽管就Python用户而言,Python信号处理程序是异步调用的,但它们只能发生在Python解释程序的“原子”指令之间。这意味着在长时间计算中实现的信号纯粹用C语言实现(例如,在大量文本上进行正则表达式匹配)可能会延迟一段任意时间。
- 当信号在I / O操作期间到达时,I / O操作可能在信号处理程序返回后引发异常。这取决于底层Unix系统关于中断系统调用的语义。
- 因为C信号处理程序总是返回,所以捕获类似
SIGFPE
或类似的同步错误是没有意义的SIGSEGV
。
- Python默认安装了少量的信号处理程序:
SIGPIPE
被忽略(因此管道和套接字上的写入错误可以作为普通的Python异常报告)并被SIGINT
转换为KeyboardInterrupt
异常。所有这些都可以被覆盖。
- 如果信号和线程在同一个程序中使用,则必须小心。在同时使用信号和线程时要记住的基本事项是:始终
signal()
在主执行线程中执行操作。任何线程可以执行alarm()
,getsignal()
,pause()
,setitimer()
或getitimer(
只有主线程可以设置一个新的信号处理程序,并且主线程将是唯一接收信号的线程(signal即使
底层线程实现支持向单个线程发送信号,这也是由Python 模块实施的)。这意味着信号不能用作线程间通信的手段。改为使用锁定。
signal
模块中定义的变量是:
signal.SIG_DFL
这是两种标准信号处理选项之一; 它将简单地执行信号的默认功能。例如,在大多数系统中,缺省操作SIGQUIT
是转储核心并退出,而默认操作SIGCHLD
是简单地忽略它。
signal.SIG_IGN
这是另一个标准的信号处理程序,它将简单地忽略给定的信号。
SIG*
所有的信号编号都是象征性地定义的。例如,挂断信号被定义为signal.SIGHUP; 变量名称与C程序中使用的名称相同,如下所示<signal.h>。' signal()' 的Unix手册页列出了现有的信号(在某些系统上,这是信号(2),在其他系统上是信号(7))。请注意,并非所有系统都定义了同一组信号名称; 只有由系统定义的名称才由该模块定义。
signal.CTRL_C_EVENT
与Ctrl+C
击键事件相对应的信号。这个信号只能用于os.kill()
。
可用性:Windows。
2.7版本的新功能。
signal.CTRL_BREAK_EVENT
与Ctrl+Break
击键事件相对应的信号。这个信号只能用于os.kill()
。
可用性:Windows。
2.7版本的新功能。
signal.NSIG
比最高信号数量多一个。
signal.ITIMER_REAL
实时减少间隔计时器,并SIGALRM
在到期时交付。
signal.ITIMER_VIRTUAL
仅在进程正在执行时递减间隔计时器,并在到期时递送SIGVTALRM。
signal.ITIMER_PROF
当进程执行时以及代表进程执行系统时,减少间隔计时器。加上ITIMER_VIRTUAL,这个计时器通常用于分析应用程序在用户和内核空间中所花费的时间。SIGPROF在到期时交付。
该signal
模块定义了一个例外:
exception signal.ItimerError
被提出来表示底层setitimer()
或getitimer()
实现中的错误。如果传递无效的间隔计时器或负时间,则会出现此错误setitimer()
。这个错误是一个子类型IOError
。
该signal
模块定义了以下功能:
signal.alarm(time)
如果时间
为非零,该函数请求一个SIGALRM
信号被发送到处理时间
秒。任何先前预定的警报都将被取消(任何时候只能安排一个警报)。然后返回的值是任何先前设置的警报传递之前的秒数。如果时间
为零,则不安排警报,并且任何预定警报都将被取消。如果返回值为零,则当前不安排警报。(请参阅Unix手册页警报(2)
。)可用性:Unix。
signal.getsignal(signalnum)
返回信号signalnum
的当前信号处理程序。返回的值可能是一个可调用的Python对象,或者是一个特殊值signal.SIG_IGN
,signal.SIG_DFL
或者None
。这里signal.SIG_IGN
意味着信号先前被忽略,signal.SIG_DFL
意味着处理信号的默认方式以前在使用中,并且None
意味着以前的信号处理程序不是从Python安装的。
signal.pause()
使进程进入休眠状态,直到收到信号; 然后会调用适当的处理程序。什么都不返回 不在Windows上。(请参阅Unix手册页信号(2)
。)
signal.setitimer(which, seconds[, interval])
给定的间隔
计时器集(之一signal.ITIMER_REAL
,signal.ITIMER_VIRTUAL
或signal.ITIMER_PROF
通过指定),其
之后触发秒
(浮子被接受时,从不同的alarm()
),并且每一个后间隔
秒
。通过指定的时间间隔
定时器,其
可以通过设置秒
至零被清除。
当间隔计时器触发时,将向该进程发送一个信号。发送的信号取决于正在使用的定时器; signal.ITIMER_REAL
将交付SIGALRM
,signal.ITIMER_VIRTUAL
发送SIGVTALRM
并signal.ITIMER_PROF
交付SIGPROF
。
旧值作为元组返回:(delay,interval)。
试图通过一个无效的间隔计时器将导致一个ItimerError
。可用性:Unix。
2.6版本中的新功能。
signal.getitimer(which)
返回由指定的给定的时间间隔定时器的当前值,其
。可用性:Unix。
2.6版本中的新功能。
signal.set_wakeup_fd(fd)
将唤醒fd
设置为fd
。当收到一个信号时,一个'\0'
字节被写入到fd
。库可以使用此功能来唤醒投票或选择呼叫,从而使信号得到完全处理。
旧的唤醒fd
被返回。fd
必须是非阻塞的。在调用轮询或再次选择之前,由库去除任何字节。
当启用线程时,只能从主线程调用此函数; 试图从其他线程调用它会导致引发ValueError
异常。
2.6版本中的新功能。
signal.siginterrupt(signalnum, flag)
更改系统调用重启行为:如果标志
为False
,系统调用将在信号signalnum
中断时重新启动,否则系统调用将被中断。什么都不返回 可用性:Unix(有关更多信息,请参见手册页siginterrupt(3)
)。
请注意,安装信号处理程序signal()
将通过以给定信号siginterrupt()
的真实标志
值隐式调用来重置重启动行为为可中断。
2.6版本中的新功能。
signal.signal(signalnum, handler)
将信号signalnum
的处理程序
设置为函数处理程序
。处理程序
可以是一个可调用的Python对象,它带有两个参数(见下文),或者一个特殊值signal.SIG_IGN
或signal.SIG_DFL
。之前的信号处理程序
将被返回(参见getsignal()
上面的描述)。(请参阅Unix手册页信号(2)
。)
当启用线程时,只能从主线程调用此函数; 试图从其他线程调用它会导致引发ValueError
异常。
该处理程序
有两个参数调用:信号编号和当前堆栈帧(None
或框架对象;有关框架对象的描述,请参阅类型层次结构中的描述或查看inspect
模块中的属性描述)。
在Windows中,signal()
只能叫SIGABRT
,SIGFPE
,SIGILL
,SIGINT
,SIGSEGV
,或SIGTERM
。A ValueError
会在其他情况下被提出。
1.例子
这是一个简单的示例程序。它使用该alarm()
函数来限制等待打开文件的时间; 如果该文件适用于可能未开启的串行设备,这通常会导致os.open()
无限期挂起,这很有用。解决方法是在打开文件之前设置5秒钟的警报; 如果操作时间太长,则会发送警报信号,并且处理程序引发异常。
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