signalSet handlers for asynchronous events为异步事件设置处理程序


This module provides mechanisms to use signal handlers in Python.该模块提供了在Python中使用信号处理程序的机制。

General rules一般规则

The signal.signal() function allows defining custom handlers to be executed when a signal is received. signal.signal()函数的作用是:定义接收到信号时要执行的自定义处理程序。A small number of default handlers are installed: SIGPIPE is ignored (so write errors on pipes and sockets can be reported as ordinary Python exceptions) and SIGINT is translated into a KeyboardInterrupt exception if the parent process has not changed it.安装了少量默认处理程序:忽略SIGPIPE(因此管道和套接字上的写入错误可以报告为普通Python异常),如果父进程未更改,则SIGINT将转换为键盘中断异常。

A handler for a particular signal, once set, remains installed until it is explicitly reset (Python emulates the BSD style interface regardless of the underlying implementation), with the exception of the handler for SIGCHLD, which follows the underlying implementation.特定信号的处理程序一旦设置,将保持安装状态,直到显式重置(Python模拟BSD风格的接口,而不管底层实现如何),但SIGCHLD的处理程序除外,该处理程序遵循底层实现。

Execution of Python signal handlersPython信号处理程序的执行

A Python signal handler does not get executed inside the low-level (C) signal handler. Python信号处理程序不会在低级(C)信号处理程序内执行。Instead, the low-level signal handler sets a flag which tells the virtual machine to execute the corresponding Python signal handler at a later point(for example at the next bytecode instruction). 相反,低级信号处理程序设置一个标志,告诉虚拟机在稍后的时间点(例如在下一个bytecode指令)执行相应的Python信号处理程序。This has consequences:这会产生以下后果:

  • It makes little sense to catch synchronous errors like SIGFPE or SIGSEGV that are caused by an invalid operation in C code. 捕获由C代码中的无效操作导致的同步错误(如SIGFPESIGSEGV)几乎没有意义。Python will return from the signal handler to the C code, which is likely to raise the same signal again, causing Python to apparently hang. Python将从信号处理程序返回到C代码,这很可能再次引发相同的信号,导致Python明显挂起。From Python 3.3 onwards, you can use the faulthandler module to report on synchronous errors.从Python 3.3开始,您可以使用faulthandler模块报告同步错误。

  • A long-running calculation implemented purely in C (such as regular expression matching on a large body of text) may run uninterrupted for an arbitrary amount of time, regardless of any signals received. 纯用C语言实现的长时间运行的计算(例如对大量文本进行正则表达式匹配)可能会在任意时间段内不间断地运行,而与接收到的任何信号无关。The Python signal handlers will be called when the calculation finishes.当计算完成时,将调用Python信号处理程序。

  • If the handler raises an exception, it will be raised “out of thin air” in the main thread. 如果处理程序引发异常,它将在主线程中“凭空”引发。See the note below for a discussion.有关讨论,请参阅下面的注释

Signals and threads信号和线程

Python signal handlers are always executed in the main Python thread of the main interpreter, even if the signal was received in another thread. Python信号处理程序总是在主解释器的主Python线程中执行,即使信号是在另一个线程中接收的。This means that signals can’t be used as a means of inter-thread communication. 这意味着信号不能用作线程间通信的手段。You can use the synchronization primitives from the threading module instead.您可以改为使用threading模块中的同步原语。

Besides, only the main thread of the main interpreter is allowed to set a new signal handler.此外,只允许主解释器的主线程设置新的信号处理程序。

Module contents模块内容

Changed in version 3.5:版本3.5中更改: signal (SIG*), handler (SIG_DFL, SIG_IGN) and sigmask (SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK) related constants listed below were turned into enums. 下面列出的信号(SIG*)、处理程序(SIG_DFLSIG_IGN)和sigmask(SIG_BLOCKSIG_UNBLOCKSIG_SETMASK)相关常数被转换为enumsgetsignal(), pthread_sigmask(), sigpending() and sigwait() functions return human-readable enums.getsignal()pthread_sigmask()sigpending()sigwait()函数返回人类可读的枚举。

The variables defined in the signal module are:signal模块中定义的变量包括:

signal.SIG_DFL

This is one of two standard signal handling options; it will simply perform the default function for the signal. 这是两种标准信号处理选项之一;它将简单地执行信号的默认功能。For example, on most systems the default action for SIGQUIT is to dump core and exit, while the default action for SIGCHLD is to simply ignore it.例如,在大多数系统上,SIGQUIT的默认操作是转储内核并退出,而SIGCHLD的默认操作则是简单地忽略它。

signal.SIG_IGN

This is another standard signal handler, which will simply ignore the given signal.这是另一个标准信号处理程序,它将简单地忽略给定的信号。

signal.SIGABRT

Abort signal from abort(3).来自abort(3)的中止信号。

signal.SIGALRM

Timer signal from alarm(2).来自alarm(2)的计时器信号。

Availability: Unix.

signal.SIGBREAK

Interrupt from keyboard (CTRL + BREAK).键盘中断(CTRL+BREAK)。

Availability: Windows.

signal.SIGBUS

Bus error (bad memory access).总线错误(内存访问错误)。

Availability: Unix.

signal.SIGCHLD

Child process stopped or terminated.子进程已停止或终止。

Availability: Unix.

signal.SIGCLD

Alias to SIGCHLD.SIGCHLD的别名。

signal.SIGCONT

Continue the process if it is currently stopped如果当前已停止,则继续该过程

Availability: Unix.

signal.SIGFPE

Floating-point exception. For example, division by zero.浮点异常。例如,除以零。

See also

ZeroDivisionError is raised when the second argument of a division or modulo operation is zero.当除法或模运算的第二个参数为零时,会引发ZeroDivisionError

signal.SIGHUP

Hangup detected on controlling terminal or death of controlling process.在控制终端上检测到挂断或控制进程终止。

Availability: Unix.

signal.SIGILL

Illegal instruction.非法指令。

signal.SIGINT

Interrupt from keyboard (CTRL + C).键盘中断(CTRL+C)。

Default action is to raise KeyboardInterrupt.默认操作是引发KeyboardInterrupt

signal.SIGKILL

Kill signal.

It cannot be caught, blocked, or ignored.无法捕获、阻止或忽略它。

Availability: Unix.

signal.SIGPIPE

Broken pipe: write to pipe with no readers.管道破裂:在没有读卡器的情况下写入管道。

Default action is to ignore the signal.默认操作是忽略信号。

Availability: Unix.

signal.SIGSEGV

Segmentation fault: invalid memory reference.分段错误:内存引用无效。

signal.SIGTERM

Termination signal.终止信号。

signal.SIGUSR1

User-defined signal 1.用户定义的信号1。

Availability: Unix.

signal.SIGUSR2

User-defined signal 2.用户定义的信号2。

Availability: Unix.

signal.SIGWINCH

Window resize signal.窗口调整大小信号。

Availability: Unix.

SIG*

All the signal numbers are defined symbolically. 所有信号编号都以符号方式定义。For example, the hangup signal is defined as signal.SIGHUP; the variable names are identical to the names used in C programs, as found in <signal.h>. The Unix man page for ‘signal()’ lists the existing signals (on some systems this is signal(2), on others the list is in signal(7)). 例如,挂断信号被定义为signal.SIGHUP;变量名与C程序中使用的名称相同,如<signal.h>中所示。“signal()”的Unix手册页列出了现有的信号(在某些系统上,这是signal(2),在其他系统上,列表在signal(7)中)。Note that not all systems define the same set of signal names; only those names defined by the system are defined by this module.注意,并非所有系统都定义相同的一组信号名称;此模块仅定义系统定义的那些名称。

signal.CTRL_C_EVENT

The signal corresponding to the Ctrl+C keystroke event. Ctrl+C击键事件相对应的信号。This signal can only be used with os.kill().此信号只能与os.kill()一起使用。

Availability: Windows.

New in version 3.2.版本3.2中新增。

signal.CTRL_BREAK_EVENT

The signal corresponding to the Ctrl+Break keystroke event. Ctrl+Break击键事件相对应的信号。This signal can only be used with os.kill().此信号只能与os.kill()一起使用。

Availability: Windows.

New in version 3.2.版本3.2中新增。

signal.NSIG

One more than the number of the highest signal number.比最高信号编号的编号多一个。

signal.ITIMER_REAL

Decrements interval timer in real time, and delivers SIGALRM upon expiration.实时减少间隔计时器,并在到期时传递SIGALRM

signal.ITIMER_VIRTUAL

Decrements interval timer only when the process is executing, and delivers SIGVTALRM upon expiration.仅当进程正在执行时递减间隔计时器,并在到期时传递SIGVTALRM。

signal.ITIMER_PROF

Decrements interval timer both when the process executes and when the system is executing on behalf of the process. 在进程执行时和系统代表进程执行时,递减间隔计时器。Coupled with ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the application in user and kernel space. 结合ITIMER_VIRTUAL,该计时器通常用于评测应用程序在用户和内核空间中花费的时间。SIGPROF is delivered upon expiration.SIGPROF在到期时交付。

signal.SIG_BLOCK

A possible value for the how parameter to pthread_sigmask() indicating that signals are to be blocked.pthread_sigmask()how参数的一个可能值,指示要阻止信号。

New in version 3.3.版本3.3中新增。

signal.SIG_UNBLOCK

A possible value for the how parameter to pthread_sigmask() indicating that signals are to be unblocked.pthread_sigmask()how参数的一个可能值,表示要取消阻止信号。

New in version 3.3.版本3.3中新增。

signal.SIG_SETMASK

A possible value for the how parameter to pthread_sigmask() indicating that the signal mask is to be replaced.pthread_sigmask()how参数的一个可能值,指示要替换信号掩码。

New in version 3.3.版本3.3中新增。

The signal module defines one exception:signal模块定义了一个例外:

exceptionsignal.ItimerError

Raised to signal an error from the underlying setitimer() or getitimer() implementation. 引发以发出来自基础setitimer()getitimer()实现的错误信号。Expect this error if an invalid interval timer or a negative time is passed to setitimer(). 如果向setitimer()传递了无效的间隔计时器或负时间,则会出现此错误。This error is a subtype of OSError.此错误是OSError的一个子类型。

New in version 3.3.版本3.3中新增。This error used to be a subtype of IOError, which is now an alias of OSError.此错误以前是IOError的子类型,现在是OSError的别名。

The signal module defines the following functions:signal模块定义以下功能:

signal.alarm(time)

If time is non-zero, this function requests that a SIGALRM signal be sent to the process in time seconds. 如果time为非零,则此函数请求以time秒为单位向进程发送SIGALRM信号。Any previously scheduled alarm is canceled (only one alarm can be scheduled at any time). 取消任何先前计划的警报(任何时候只能计划一个警报)。The returned value is then the number of seconds before any previously set alarm was to have been delivered. 然后,返回的值是任何先前设置的警报发出之前的秒数。If time is zero, no alarm is scheduled, and any scheduled alarm is canceled. 如果time为零,则不计划任何报警,并且取消任何计划的报警。If the return value is zero, no alarm is currently scheduled.如果返回值为零,则当前未计划报警。

Availability: Unix. See the man page alarm(2) for further information.有关更多信息,请参阅手册页alarm(2)

signal.getsignal(signalnum)

Return the current signal handler for the signal signalnum. 返回信号signalnum的当前信号处理程序。The returned value may be a callable Python object, or one of the special values signal.SIG_IGN, signal.SIG_DFL or None. 返回的值可以是可调用的Python对象,也可以是特殊值signal.SIG_IGNsignal.SIG_DFLNone之一。Here, signal.SIG_IGN means that the signal was previously ignored, signal.SIG_DFL means that the default way of handling the signal was previously in use, and None means that the previous signal handler was not installed from Python.这里,signal.SIG_IGN表示信号先前被忽略,signal.SIG_DFL表示处理信号的默认方式先前被使用,None表示先前的信号处理程序不是从Python安装的。

signal.strsignal(signalnum)

Return the system description of the signal signalnum, such as “Interrupt”, “Segmentation fault”, etc. 返回信号signalnum的系统描述,如“中断”、“分段故障”等。Returns None if the signal is not recognized.如果无法识别信号,则返回None

New in version 3.8.版本3.8中新增。

signal.valid_signals()

Return the set of valid signal numbers on this platform. 返回此平台上的一组有效信号号。This can be less than range(1, NSIG) if some signals are reserved by the system for internal use.如果系统保留一些信号供内部使用,则该值可能小于范围range(1, NSIG)

New in version 3.8.版本3.8中新增。

signal.pause()

Cause the process to sleep until a signal is received; the appropriate handler will then be called. 使进程休眠,直到接收到信号;然后将调用适当的处理程序。Returns nothing.不返回任何内容。

Availability: Unix. See the man page signal(2) for further information.有关更多信息,请参阅手册页signal(2)

See also sigwait(), sigwaitinfo(), sigtimedwait() and sigpending().另请参见sigwait()sigwaitinfo()sigtimedwait()sigpending()

signal.raise_signal(signum)

Sends a signal to the calling process. 向调用进程发送信号。Returns nothing.不返回任何内容。

New in version 3.8.版本3.8中新增。

signal.pidfd_send_signal(pidfd, sig, siginfo=None, flags=0)

Send signal sig to the process referred to by file descriptor pidfd. 向文件描述符pidfd所指的进程发送信号sigPython does not currently support the siginfo parameter; it must be None. Python当前不支持siginfo参数;它必须是NoneThe flags argument is provided for future extensions; no flag values are currently defined.flags参数是为将来的扩展提供的;当前未定义标志值。

See the pidfd_send_signal(2) man page for more information.有关详细信息,请参阅pidfd_send_signal(2)手册页。

Availability: Linux 5.1+

New in version 3.9.版本3.9中新增。

signal.pthread_kill(thread_id, signalnum)

Send the signal signalnum to the thread thread_id, another thread in the same process as the caller. 将信号signalnum发送给线程thread_id,该线程是与调用者处于同一进程中的另一个线程。The target thread can be executing any code (Python or not). 目标线程可以执行任何代码(Python或非Python)。However, if the target thread is executing the Python interpreter, the Python signal handlers will be executed by the main thread of the main interpreter. 但是,如果目标线程正在执行Python解释器,则Python信号处理程序将由主解释器的主线程执行。Therefore, the only point of sending a signal to a particular Python thread would be to force a running system call to fail with InterruptedError.因此,向特定Python线程发送信号的唯一目的是强制正在运行的系统调用失败,并显示InterruptedError

Use threading.get_ident() or the ident attribute of threading.Thread objects to get a suitable value for thread_id.使用threading.get_ident()threading.Thread对象的ident属性获取thread_id的适当值。

If signalnum is 0, then no signal is sent, but error checking is still performed; this can be used to check if the target thread is still running.如果signanum为0,则不发送信号,但仍执行错误检查;这可用于检查目标线程是否仍在运行。

Raises an auditing event signal.pthread_kill with arguments thread_id, signalnum.使用参数thread_idsignalnum引发审计事件signal.pthread_kill

Availability: Unix. See the man page pthread_kill(3) for further information.有关更多信息,请参阅手册页pthread_kill(3)

See also os.kill().另请参见os.kill()

New in version 3.3.版本3.3中新增。

signal.pthread_sigmask(how, mask)

Fetch and/or change the signal mask of the calling thread. 获取和/或更改调用线程的信号掩码。The signal mask is the set of signals whose delivery is currently blocked for the caller. 信号掩码是当前阻止呼叫者传送的一组信号。Return the old signal mask as a set of signals.将旧信号掩码作为一组信号返回。

The behavior of the call is dependent on the value of how, as follows.调用的行为取决于how的值,如下所示。

  • SIG_BLOCK: The set of blocked signals is the union of the current set and the mask argument.:阻塞信号集合是当前集合和mask参数的并集。

  • SIG_UNBLOCK: The signals in mask are removed from the current set of blocked signals. mask中的信号将从当前阻止信号集中删除。It is permissible to attempt to unblock a signal which is not blocked.允许尝试解锁未被阻止的信号。

  • SIG_SETMASK: The set of blocked signals is set to the mask argument.:屏蔽信号集设置为mask参数。

mask is a set of signal numbers (e.g. {signal.SIGINT, signal.SIGTERM}). mask是一组信号号(例如{signal.SIGINT, signal.SIGTERM})。Use valid_signals() for a full mask including all signals.对于包含所有信号的完整掩码,请使用valid_signals()

For example, signal.pthread_sigmask(signal.SIG_BLOCK, []) reads the signal mask of the calling thread.例如,signal.pthread_sigmask(signal.SIG_BLOCK, [])读取调用线程的信号掩码。

SIGKILL and SIGSTOP cannot be blocked.无法阻止SIGKILLSIGSTOP

Availability: Unix. See the man page sigprocmask(2) and pthread_sigmask(3) for further information.有关更多信息,请参阅手册页sigprocmask(2)pthread_sigmask(3)

See also pause(), sigpending() and sigwait().另请参见pause()sigpending()sigwait()

New in version 3.3.版本3.3中新增。

signal.setitimer(which, seconds, interval=0.0)

Sets given interval timer (one of signal.ITIMER_REAL, signal.ITIMER_VIRTUAL or signal.ITIMER_PROF) specified by which to fire after seconds (float is accepted, different from alarm()) and after that every interval seconds (if interval is non-zero). 设置由which指定的给定间隔计时器(signal.ITIMER_REALsignal.ITIMER_VIRTUALsignal.ITIMER_PROF之一),在seconds后(接受浮点,不同于alarm())和之后的每个间隔秒(如果间隔为非零)触发该计时器。The interval timer specified by which can be cleared by setting seconds to zero.which指定的间隔计时器,可通过将seconds设置为零来清除。

When an interval timer fires, a signal is sent to the process. 当间隔计时器启动时,将向进程发送一个信号。The signal sent is dependent on the timer being used; signal.ITIMER_REAL will deliver SIGALRM, signal.ITIMER_VIRTUAL sends SIGVTALRM, and signal.ITIMER_PROF will deliver SIGPROF.发送的信号取决于所使用的定时器;signal.ITIMER_REAL将发送SIGALRMsignal.ITIMER_VIRTUAL发送SIGVTALRM,而signal.ITIMER_PROF将发送SIGPROF

The old values are returned as a tuple: (delay, interval).旧值以元组形式返回:(delay,interval)。

Attempting to pass an invalid interval timer will cause an ItimerError.试图传递无效的间隔计时器将导致ItimerError

Availability: Unix.

signal.getitimer(which)

Returns current value of a given interval timer specified by which.返回由which指定的给定间隔计时器的当前值。

Availability: Unix.

signal.set_wakeup_fd(fd, *, warn_on_full_buffer=True)

Set the wakeup file descriptor to fd. 将唤醒文件描述符设置为fdWhen a signal is received, the signal number is written as a single byte into the fd. 当接收到信号时,信号号作为单个字节写入fdThis can be used by a library to wakeup a poll or select call, allowing the signal to be fully processed.这可以被库用来唤醒轮询或选择呼叫,从而允许信号被完全处理。

The old wakeup fd is returned (or -1 if file descriptor wakeup was not enabled). 返回旧的唤醒fd(如果未启用文件描述符唤醒,则返回-1)。If fd is -1, file descriptor wakeup is disabled. 如果fd为-1,则禁用文件描述符唤醒。If not -1, fd must be non-blocking. 如果不是-1,fd必须是非阻塞的。It is up to the library to remove any bytes from fd before calling poll or select again.在再次调用poll或select之前,由库删除fd中的任何字节。

When threads are enabled, this function can only be called from the main thread of the main interpreter; attempting to call it from other threads will cause a ValueError exception to be raised.当线程被启用时,该函数只能从主解释器的主线程调用;尝试从其他线程调用它将导致引发ValueError异常。

There are two common ways to use this function. 使用此函数有两种常用方法。In both approaches, you use the fd to wake up when a signal arrives, but then they differ in how they determine which signal or signals have arrived.在这两种方法中,当信号到达时,您使用fd来唤醒,但它们在如何确定which信号或哪些信号已经到达方面有所不同。

In the first approach, we read the data out of the fd’s buffer, and the byte values give you the signal numbers. 在第一种方法中,我们从fd的缓冲区中读取数据,字节值为您提供信号编号。This is simple, but in rare cases it can run into a problem: generally the fd will have a limited amount of buffer space, and if too many signals arrive too quickly, then the buffer may become full, and some signals may be lost. 这很简单,但在极少数情况下会遇到问题:通常fd的缓冲区空间有限,如果太多信号到达太快,那么缓冲区可能会变满,一些信号可能会丢失。If you use this approach, then you should set warn_on_full_buffer=True, which will at least cause a warning to be printed to stderr when signals are lost.如果使用此方法,则应将warn_on_full_buffer=True设置为True,这至少会在信号丢失时将警告打印到stderr。

In the second approach, we use the wakeup fd only for wakeups, and ignore the actual byte values. 在第二种方法中,我们只对唤醒使用唤醒fd,而忽略实际的字节值。In this case, all we care about is whether the fd’s buffer is empty or non-empty; a full buffer doesn’t indicate a problem at all. 在这种情况下,我们只关心fd的缓冲区是空的还是非空的;满缓冲区根本不表示有问题。If you use this approach, then you should set warn_on_full_buffer=False, so that your users are not confused by spurious warning messages.如果使用这种方法,那么应该将warn_on_full_buffer=False设置为False,这样用户就不会被虚假的警告消息所迷惑。

Changed in version 3.5:版本3.5中更改: On Windows, the function now also supports socket handles.在Windows上,该函数现在还支持套接字句柄。

Changed in version 3.7:版本3.7中更改: Added warn_on_full_buffer parameter.添加了warn_on_full_buffer参数。

signal.siginterrupt(signalnum, flag)

Change system call restart behaviour: if flag is False, system calls will be restarted when interrupted by signal signalnum, otherwise system calls will be interrupted. 更改系统调用重新启动行为:如果flagFalse,系统调用将在被信号signalnum中断时重新启动,否则系统调用将被中断。Returns nothing.不返回任何内容。

Availability: Unix. See the man page siginterrupt(3) for further information.有关更多信息,请参阅手册页siginterrupt(3)

Note that installing a signal handler with signal() will reset the restart behaviour to interruptible by implicitly calling siginterrupt() with a true flag value for the given signal.请注意,使用signal()安装信号处理程序将通过使用给定信号的真flag值隐式调用siginterrupt()将重启行为重置为可中断。

signal.signal(signalnum, handler)

Set the handler for signal signalnum to the function handler. 将信号signalnum的处理程序设置为函数handlerhandler can be a callable Python object taking two arguments (see below), or one of the special values signal.SIG_IGN or signal.SIG_DFL. handler可以是一个接受两个参数的可调用Python对象(见下文),也可以是特殊值signal.SIG_IGNsignal.SIG_DFL之一。The previous signal handler will be returned (see the description of getsignal() above). 将返回上一个信号处理程序(请参阅上面getsignal()的描述)。(See the Unix man page signal(2) for further information.)(有关详细信息,请参阅Unix手册页signal(2)。)

When threads are enabled, this function can only be called from the main thread of the main interpreter; attempting to call it from other threads will cause a ValueError exception to be raised.当线程被启用时,该函数只能从主解释器的主线程调用;尝试从其他线程调用它将导致引发ValueError异常。

The handler is called with two arguments: the signal number and the current stack frame (None or a frame object; for a description of frame objects, see the description in the type hierarchy or see the attribute descriptions in the inspect module).使用两个参数调用handler:信号号和当前堆栈帧(None或帧对象;有关帧对象的描述,请参阅类型层次结构中的描述或inspect模块中的属性描述)。

On Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, or SIGBREAK. 在Windows上,signal()只能用SIGABRTSIGFPESIGILLSIGINTSIGSEGVSIGTERMSIGBREAK调用。A ValueError will be raised in any other case. Note that not all systems define the same set of signal names; an AttributeError will be raised if a signal name is not defined as SIG* module level constant.在任何其他情况下都会引发ValueError。注意,并非所有系统都定义相同的一组信号名称;如果信号名称未定义为SIG*模块级常量,则会引发AttributeError

signal.sigpending()

Examine the set of signals that are pending for delivery to the calling thread (i.e., the signals which have been raised while blocked). 检查等待传递到调用线程的一组信号(即,在被阻止时发出的信号)。Return the set of the pending signals.返回一组待定信号。

Availability: Unix. See the man page sigpending(2) for further information.有关更多信息,请参阅手册页sigpending(2)

See also pause(), pthread_sigmask() and sigwait().另请参见pause()pthread_sigmask()sigwait()

New in version 3.3.版本3.3中新增。

signal.sigwait(sigset)

Suspend execution of the calling thread until the delivery of one of the signals specified in the signal set sigset. 暂停调用线程的执行,直到传递信号集sigset中指定的信号之一。The function accepts the signal (removes it from the pending list of signals), and returns the signal number.该函数接受信号(将其从挂起的信号列表中删除),并返回信号编号。

Availability: Unix. See the man page sigwait(3) for further information.有关更多信息,请参阅手册页sigwait(3)

See also pause(), pthread_sigmask(), sigpending(), sigwaitinfo() and sigtimedwait().另请参见pause()pthread_sigmask()sigpending()sigwaitinfo()sigtimedwait()

New in version 3.3.版本3.3中新增。

signal.sigwaitinfo(sigset)

Suspend execution of the calling thread until the delivery of one of the signals specified in the signal set sigset. 暂停调用线程的执行,直到传递信号集sigset中指定的信号之一。The function accepts the signal and removes it from the pending list of signals. 该函数接受信号并将其从挂起的信号列表中删除。If one of the signals in sigset is already pending for the calling thread, the function will return immediately with information about that signal. 如果sigset中的一个信号对于调用线程已经挂起,则函数将立即返回该信号的相关信息。The signal handler is not called for the delivered signal. 未为传递的信号调用信号处理程序。The function raises an InterruptedError if it is interrupted by a signal that is not in sigset.如果被不在sigset中的信号中断,该函数将引发InterruptedError

The return value is an object representing the data contained in the siginfo_t structure, namely: si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band.返回值是一个对象,表示siginfo_t结构中包含的数据,即:si_signosi_codesi_errnosi_pidsi_uidsi_statussi_band

Availability: Unix. See the man page sigwaitinfo(2) for further information.有关更多信息,请参阅手册页sigwaitinfo(2)

See also pause(), sigwait() and sigtimedwait().另请参见pause()sigwait()sigtimedwait()

New in version 3.3.版本3.3中新增。

Changed in version 3.5:版本3.5中更改: The function is now retried if interrupted by a signal not in sigset and the signal handler does not raise an exception (see PEP 475 for the rationale).如果被不在sigset中的信号中断,并且信号处理程序没有引发异常,则现在重试该函数(有关原理,请参阅PEP 475)。

signal.sigtimedwait(sigset, timeout)

Like sigwaitinfo(), but takes an additional timeout argument specifying a timeout. sigwaitinfo()类似,但需要一个额外的timeout参数来指定超时。If timeout is specified as 0, a poll is performed. 如果timeout指定为0,则执行轮询。Returns None if a timeout occurs.如果发生超时,则返回None

Availability: Unix. See the man page sigtimedwait(2) for further information.有关更多信息,请参阅手册页sigtimedwait(2)

See also pause(), sigwait() and sigwaitinfo().另请参见pause()sigwait()sigwaitinfo()

New in version 3.3.版本3.3中新增。

Changed in version 3.5:版本3.5中更改: The function is now retried with the recomputed timeout if interrupted by a signal not in sigset and the signal handler does not raise an exception (see PEP 475 for the rationale).如果被不在sigset中的信号中断,并且信号处理程序没有引发异常,则现在使用重新计算的timeout重试该函数(有关原理,请参阅PEP 475)。

Example示例

Here is a minimal example program. 这里是一个最小的示例程序。It uses the alarm() function to limit the time spent waiting to open a file; this is useful if the file is for a serial device that may not be turned on, which would normally cause the os.open() to hang indefinitely. 它使用alarm()函数来限制等待打开文件所花费的时间;如果文件用于可能未打开的串行设备,这将非常有用,这通常会导致os.open()无限期挂起。The solution is to set a 5-second alarm before opening the file; if the operation takes too long, the alarm signal will be sent, and the handler raises an exception.解决方案是在打开文件之前设置5秒警报;如果操作花费的时间太长,将发送报警信号,处理程序将引发异常。

import signal, os
def handler(signum, frame):
print('Signal handler called with signal', signum)
raise OSError("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

Note on SIGPIPE

Piping output of your program to tools like head(1) will cause a SIGPIPE signal to be sent to your process when the receiver of its standard output closes early. 当标准输出的接收器提前关闭时,将程序的输出管道到head(1)等工具将导致SIGPIPE信号发送到进程。This results in an exception like BrokenPipeError: [Errno 32] Broken pipe. 这会导致类似BrokenPipeError: [Errno 32] Broken pipe管道破裂的异常。To handle this case, wrap your entry point to catch this exception as follows:要处理这种情况,请按如下方式包装入口点以捕获此异常:

import os
import sys
def main():
try:
# simulate large output (your code replaces this loop)
for x in range(10000):
print("y")
# flush output here to force SIGPIPE to be triggered
# while inside this try block.
sys.stdout.flush()
except BrokenPipeError:
# Python flushes standard streams on exit; redirect remaining output
# to devnull to avoid another BrokenPipeError at shutdown
devnull = os.open(os.devnull, os.O_WRONLY)
os.dup2(devnull, sys.stdout.fileno())
sys.exit(1) # Python exits with error code 1 on EPIPE

if __name__ == '__main__':
main()

Do not set SIGPIPE’s disposition to SIG_DFL in order to avoid BrokenPipeError. 不要将SIGPIPE的处置设置为SIG_DFL,以避免BrokenPipeErrorDoing that would cause your program to exit unexpectedly whenever any socket connection is interrupted while your program is still writing to it.这样做会导致程序在任何套接字连接中断时意外退出,而程序仍在写入套接字连接。

Note on Signal Handlers and Exceptions关于信号处理程序和异常的说明

If a signal handler raises an exception, the exception will be propagated to the main thread and may be raised after any bytecode instruction. 如果信号处理程序引发异常,则异常将传播到主线程,并可能在任何bytecode指令之后引发。Most notably, a KeyboardInterrupt may appear at any point during execution. 最值得注意的是,在执行过程中的任何时候都可能出现KeyboardInterruptMost Python code, including the standard library, cannot be made robust against this, and so a KeyboardInterrupt (or any other exception resulting from a signal handler) may on rare occasions put the program in an unexpected state.大多数Python代码(包括标准库)都无法对此进行健壮处理,因此KeyboardInterrupt(或信号处理程序导致的任何其他异常)可能会在极少数情况下使程序处于意外状态。

To illustrate this issue, consider the following code:要说明此问题,请考虑以下代码:

class SpamContext:
def __init__(self):
self.lock = threading.Lock()
def __enter__(self):
# If KeyboardInterrupt occurs here, everything is fine
self.lock.acquire()
# If KeyboardInterrupt occcurs here, __exit__ will not be called
...
# KeyboardInterrupt could occur just before the function returns

def __exit__(self, exc_type, exc_val, exc_tb):
...
self.lock.release()

For many programs, especially those that merely want to exit on KeyboardInterrupt, this is not a problem, but applications that are complex or require high reliability should avoid raising exceptions from signal handlers. 对于许多程序,尤其是那些只想在KeyboardInterrupt上退出的程序,这不是问题,但复杂或需要高可靠性的应用程序应该避免从信号处理程序引发异常。They should also avoid catching KeyboardInterrupt as a means of gracefully shutting down. 他们还应避免将KeyboardInterrupt作为优雅关闭的一种方式。Instead, they should install their own SIGINT handler. 相反,他们应该安装自己的SIGINT处理程序。Below is an example of an HTTP server that avoids KeyboardInterrupt:以下是避免KeyboardInterrupt的HTTP服务器示例:

import signal
import socket
from selectors import DefaultSelector, EVENT_READ
from http.server import HTTPServer, SimpleHTTPRequestHandler
interrupt_read, interrupt_write = socket.socketpair()

def handler(signum, frame):
print('Signal handler called with signal', signum)
interrupt_write.send(b'\0')
signal.signal(signal.SIGINT, handler)

def serve_forever(httpd):
sel = DefaultSelector()
sel.register(interrupt_read, EVENT_READ)
sel.register(httpd, EVENT_READ)

while True:
for key, _ in sel.select():
if key.fileobj == interrupt_read:
interrupt_read.recv(1)
return
if key.fileobj == httpd:
httpd.handle_request()

print("Serving on port 8000")
httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler)
serve_forever(httpd)
print("Shutdown...")