在线文档教程

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_IGNsignal.SIG_DFL或者None。这里signal.SIG_IGN意味着信号先前被忽略,signal.SIG_DFL意味着处理信号的默认方式以前在使用中,并且None意味着以前的信号处理程序不是从Python安装的。

signal.pause()

使进程进入休眠状态,直到收到信号; 然后会调用适当的处理程序。什么都不返回 不在Windows上。(请参阅Unix手册页信号(2)。)

signal.setitimer(which, seconds[, interval])

给定的间隔计时器集(之一signal.ITIMER_REALsignal.ITIMER_VIRTUALsignal.ITIMER_PROF通过指定),其之后触发(浮子被接受时,从不同的alarm()),并且每一个后间隔。通过指定的时间间隔定时器,其可以通过设置至零被清除。

当间隔计时器触发时,将向该进程发送一个信号。发送的信号取决于正在使用的定时器; signal.ITIMER_REAL将交付SIGALRMsignal.ITIMER_VIRTUAL发送SIGVTALRMsignal.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_IGNsignal.SIG_DFL。之前的信号处理程序将被返回(参见getsignal()上面的描述)。(请参阅Unix手册页信号(2)。)

当启用线程时,只能从主线程调用此函数; 试图从其他线程调用它会导致引发ValueError异常。

处理程序有两个参数调用:信号编号和当前堆栈帧(None或框架对象;有关框架对象的描述,请参阅类型层次结构中的描述或查看inspect模块中的属性描述)。

在Windows中,signal()只能叫SIGABRTSIGFPESIGILLSIGINTSIGSEGV,或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