mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 23:14:06 +08:00
15 lines
47 KiB
HTML
15 lines
47 KiB
HTML
<div class="body" role="main"><div class="section" id="module-signal"><h1><span class="yiyi-st" id="yiyi-10">18.8. <a class="reference internal" href="#module-signal" title="signal: Set handlers for asynchronous events."><code class="xref py py-mod docutils literal"><span class="pre">signal</span></code></a> - 设置异步事件处理程序</span></h1><p><span class="yiyi-st" id="yiyi-11">此模块提供了在Python中使用信号处理程序的机制。</span></p><div class="section" id="general-rules"><h2><span class="yiyi-st" id="yiyi-12">18.8.1. </span><span class="yiyi-st" id="yiyi-13">General rules</span></h2><p><span class="yiyi-st" id="yiyi-14"><a class="reference internal" href="#signal.signal" title="signal.signal"><code class="xref py py-func docutils literal"><span class="pre">signal.signal()</span></code></a>函数允许定义在接收到信号时执行的自定义处理程序。</span><span class="yiyi-st" id="yiyi-15">安装了少量默认处理程序:<code class="xref py py-const docutils literal"><span class="pre">SIGPIPE</span></code>被忽略(因此管道和套接字上的写入错误可以报告为普通Python异常),<code class="xref py py-const docutils literal"><span class="pre">SIGINT</span></code>被转换为<a class="reference internal" href="exceptions.html#KeyboardInterrupt" title="KeyboardInterrupt"><code class="xref py py-exc docutils literal"><span class="pre">KeyboardInterrupt</span></code></a>异常。</span></p><p><span class="yiyi-st" id="yiyi-16">特定信号的处理程序一旦设置,将保持安装状态,直到显式复位(不管底层实现如何,Python都会模拟BSD样式接口),除了<code class="xref py py-const docutils literal"><span class="pre">SIGCHLD</span></code>的处理程序底层实现。</span></p><div class="section" id="execution-of-python-signal-handlers"><h3><span class="yiyi-st" id="yiyi-17">18.8.1.1. </span><span class="yiyi-st" id="yiyi-18">Execution of Python signal handlers</span></h3><p><span class="yiyi-st" id="yiyi-19">Python信号处理程序不会在低级(C)信号处理程序内部执行。</span><span class="yiyi-st" id="yiyi-20">相反,低级信号处理程序在稍后的点(例如在下一个<a class="reference internal" href="../glossary.html#term-bytecode"><span class="xref std std-term">bytecode</span></a>指令处)设置告知<a class="reference internal" href="../glossary.html#term-virtual-machine"><span class="xref std std-term">virtual machine</span></a>执行相应的Python信号处理程序的标志。</span><span class="yiyi-st" id="yiyi-21">这有后果:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-22">捕获由C代码中的无效操作导致的类似于<code class="xref py py-const docutils literal"><span class="pre">SIGFPE</span></code>或<code class="xref py py-const docutils literal"><span class="pre">SIGSEGV</span></code>的同步错误没有什么意义。</span><span class="yiyi-st" id="yiyi-23">Python将从信号处理程序返回到C代码,这可能再次引发相同的信号,导致Python显然挂起。</span><span class="yiyi-st" id="yiyi-24">从Python 3.3开始,您可以使用<a class="reference internal" href="faulthandler.html#module-faulthandler" title="faulthandler: Dump the Python traceback."><code class="xref py py-mod docutils literal"><span class="pre">faulthandler</span></code></a>模块报告同步错误。</span></li><li><span class="yiyi-st" id="yiyi-25">完全在C中执行的长时间运行的计算(例如对大量文本的正则表达式匹配)可以不间断地运行任意时间量,而不管接收到任何信号。</span><span class="yiyi-st" id="yiyi-26">Python信号处理程序将在计算完成时调用。</span></li></ul></div><div class="section" id="signals-and-threads"><h3><span class="yiyi-st" id="yiyi-27">18.8.1.2. </span><span class="yiyi-st" id="yiyi-28">Signals and threads</span></h3><p><span class="yiyi-st" id="yiyi-29">Python信号处理程序总是在主Python线程中执行,即使信号在另一个线程中被接收。</span><span class="yiyi-st" id="yiyi-30">这意味着信号不能用作线程间通信的手段。</span><span class="yiyi-st" id="yiyi-31">您可以使用来自<a class="reference internal" href="threading.html#module-threading" title="threading: Thread-based parallelism."><code class="xref py py-mod docutils literal"><span class="pre">threading</span></code></a>模块的同步原语。</span></p><p><span class="yiyi-st" id="yiyi-32">此外,只有主线程允许设置一个新的信号处理程序。</span></p></div></div><div class="section" id="module-contents"><h2><span class="yiyi-st" id="yiyi-33">18.8.2. </span><span class="yiyi-st" id="yiyi-34">Module contents</span></h2><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-35"><span class="versionmodified">在版本3.5中更改了</span>信号(SIG *),处理程序(<a class="reference internal" href="#signal.SIG_DFL" title="signal.SIG_DFL"><code class="xref py py-const docutils literal"><span class="pre">SIG_DFL</span></code></a>,<a class="reference internal" href="#signal.SIG_IGN" title="signal.SIG_IGN"><code class="xref py py-const docutils literal"><span class="pre">SIG_IGN</span></code></a>)和sigmask(<a class="reference internal" href="#signal.SIG_BLOCK" title="signal.SIG_BLOCK"><code class="xref py py-const docutils literal"><span class="pre">SIG_BLOCK</span></code></a> <a class="reference internal" href="#signal.SIG_UNBLOCK" title="signal.SIG_UNBLOCK"><code class="xref py py-const docutils literal"><span class="pre">SIG_UNBLOCK</span></code></a>,<a class="reference internal" href="#signal.SIG_SETMASK" title="signal.SIG_SETMASK"><code class="xref py py-const docutils literal"><span class="pre">SIG_SETMASK</span></code></a>)相关常数变成<a class="reference internal" href="enum.html#enum.IntEnum" title="enum.IntEnum"><code class="xref py py-class docutils literal"><span class="pre">enums</span></code></a>。</span><span class="yiyi-st" id="yiyi-36"><a class="reference internal" href="#signal.getsignal" title="signal.getsignal"><code class="xref py py-func docutils literal"><span class="pre">getsignal()</span></code></a>, <a class="reference internal" href="#signal.pthread_sigmask" title="signal.pthread_sigmask"><code class="xref py py-func docutils literal"><span class="pre">pthread_sigmask()</span></code></a>, <a class="reference internal" href="#signal.sigpending" title="signal.sigpending"><code class="xref py py-func docutils literal"><span class="pre">sigpending()</span></code></a> and <a class="reference internal" href="#signal.sigwait" title="signal.sigwait"><code class="xref py py-func docutils literal"><span class="pre">sigwait()</span></code></a> functions return human-readable <a class="reference internal" href="enum.html#enum.IntEnum" title="enum.IntEnum"><code class="xref py py-class docutils literal"><span class="pre">enums</span></code></a>.</span></p></div><p><span class="yiyi-st" id="yiyi-37">在<a class="reference internal" href="#module-signal" title="signal: Set handlers for asynchronous events."><code class="xref py py-mod docutils literal"><span class="pre">signal</span></code></a>模块中定义的变量是:</span></p><dl class="data"><dt id="signal.SIG_DFL"><span class="yiyi-st" id="yiyi-38"> <code class="descclassname">signal.</code><code class="descname">SIG_DFL</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-39">这是两个标准信号处理选项之一;它将简单地执行信号的默认功能。</span><span class="yiyi-st" id="yiyi-40">例如,在大多数系统上,<code class="xref py py-const docutils literal"><span class="pre">SIGQUIT</span></code>的默认操作是转储核心和退出,而<code class="xref py py-const docutils literal"><span class="pre">SIGCHLD</span></code>的默认操作是简单地忽略它。</span></p></dd></dl><dl class="data"><dt id="signal.SIG_IGN"><span class="yiyi-st" id="yiyi-41"> <code class="descclassname">signal.</code><code class="descname">SIG_IGN</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-42">这是另一个标准信号处理程序,它将简单地忽略给定的信号。</span></p></dd></dl><dl class="data"><dt><span class="yiyi-st" id="yiyi-43"><code class="descname">SIG *</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-44">所有信号编号都用符号定义。</span><span class="yiyi-st" id="yiyi-45">例如,挂起信号定义为<code class="xref py py-const docutils literal"><span class="pre">signal.SIGHUP</span></code>;变量名称与C程序中使用的名称相同,如<code class="docutils literal"><span class="pre"><signal.h></span></code>中所述。</span><span class="yiyi-st" id="yiyi-46">The Unix man page for ‘<code class="xref c c-func docutils literal"><span class="pre">signal()</span></code>‘ lists the existing signals (on some systems this is <em class="manpage">signal(2)</em>, on others the list is in <em class="manpage">signal(7)</em>). </span><span class="yiyi-st" id="yiyi-47">请注意,并非所有系统都定义相同的信号名称集;只有由系统定义的那些名称由此模块定义。</span></p></dd></dl><dl class="data"><dt id="signal.CTRL_C_EVENT"><span class="yiyi-st" id="yiyi-48"> <code class="descclassname">signal.</code><code class="descname">CTRL_C_EVENT</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-49">对应于<code class="kbd docutils literal"><span class="pre">Ctrl+C</span></code>击键事件的信号。</span><span class="yiyi-st" id="yiyi-50">此信号只能与<a class="reference internal" href="os.html#os.kill" title="os.kill"><code class="xref py py-func docutils literal"><span class="pre">os.kill()</span></code></a>一起使用。</span></p><p><span class="yiyi-st" id="yiyi-51">可用性:Windows。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-52"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="signal.CTRL_BREAK_EVENT"><span class="yiyi-st" id="yiyi-53"> <code class="descclassname">signal.</code><code class="descname">CTRL_BREAK_EVENT</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-54">对应于<code class="kbd docutils literal"><span class="pre">Ctrl+Break</span></code>击键事件的信号。</span><span class="yiyi-st" id="yiyi-55">此信号只能与<a class="reference internal" href="os.html#os.kill" title="os.kill"><code class="xref py py-func docutils literal"><span class="pre">os.kill()</span></code></a>一起使用。</span></p><p><span class="yiyi-st" id="yiyi-56">可用性:Windows。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-57"><span class="versionmodified">版本3.2中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="signal.NSIG"><span class="yiyi-st" id="yiyi-58"> <code class="descclassname">signal.</code><code class="descname">NSIG</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-59">一个多于最高信号数的数。</span></p></dd></dl><dl class="data"><dt id="signal.ITIMER_REAL"><span class="yiyi-st" id="yiyi-60"> <code class="descclassname">signal.</code><code class="descname">ITIMER_REAL</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-61">实时递减间隔定时器,并在到期时递送<code class="xref py py-const docutils literal"><span class="pre">SIGALRM</span></code>。</span></p></dd></dl><dl class="data"><dt id="signal.ITIMER_VIRTUAL"><span class="yiyi-st" id="yiyi-62"> <code class="descclassname">signal.</code><code class="descname">ITIMER_VIRTUAL</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-63">仅在进程正在执行时减少间隔定时器,并在到期时传递SIGVTALRM。</span></p></dd></dl><dl class="data"><dt id="signal.ITIMER_PROF"><span class="yiyi-st" id="yiyi-64"> <code class="descclassname">signal.</code><code class="descname">ITIMER_PROF</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-65">递减间隔定时器,当进程执行时和系统代表进程执行时。</span><span class="yiyi-st" id="yiyi-66">与ITIMER_VIRTUAL相耦合,此定时器通常用于配置应用程序在用户和内核空间中花费的时间。</span><span class="yiyi-st" id="yiyi-67">SIGPROF在到期时交付。</span></p></dd></dl><dl class="data"><dt id="signal.SIG_BLOCK"><span class="yiyi-st" id="yiyi-68"> <code class="descclassname">signal.</code><code class="descname">SIG_BLOCK</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-69"><em>如何</em>参数到<a class="reference internal" href="#signal.pthread_sigmask" title="signal.pthread_sigmask"><code class="xref py py-func docutils literal"><span class="pre">pthread_sigmask()</span></code></a>的可能值,表示要阻止信号。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-70"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="signal.SIG_UNBLOCK"><span class="yiyi-st" id="yiyi-71"> <code class="descclassname">signal.</code><code class="descname">SIG_UNBLOCK</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-72"><em>如何</em>参数到<a class="reference internal" href="#signal.pthread_sigmask" title="signal.pthread_sigmask"><code class="xref py py-func docutils literal"><span class="pre">pthread_sigmask()</span></code></a>的可能值,表示要解除阻塞信号。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-73"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="data"><dt id="signal.SIG_SETMASK"><span class="yiyi-st" id="yiyi-74"> <code class="descclassname">signal.</code><code class="descname">SIG_SETMASK</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-75"><em>如何</em>参数到<a class="reference internal" href="#signal.pthread_sigmask" title="signal.pthread_sigmask"><code class="xref py py-func docutils literal"><span class="pre">pthread_sigmask()</span></code></a>的可能值,表示要替换信号掩码。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-76"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-77"><a class="reference internal" href="#module-signal" title="signal: Set handlers for asynchronous events."><code class="xref py py-mod docutils literal"><span class="pre">signal</span></code></a>模块定义了一个例外:</span></p><dl class="exception"><dt id="signal.ItimerError"><span class="yiyi-st" id="yiyi-78"> <em class="property">exception </em><code class="descclassname">signal.</code><code class="descname">ItimerError</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-79">引发来自底层<a class="reference internal" href="#signal.setitimer" title="signal.setitimer"><code class="xref py py-func docutils literal"><span class="pre">setitimer()</span></code></a>或<a class="reference internal" href="#signal.getitimer" title="signal.getitimer"><code class="xref py py-func docutils literal"><span class="pre">getitimer()</span></code></a>实现的错误信号。</span><span class="yiyi-st" id="yiyi-80">如果将无效的间隔定时器或负时间传递到<a class="reference internal" href="#signal.setitimer" title="signal.setitimer"><code class="xref py py-func docutils literal"><span class="pre">setitimer()</span></code></a>,则会发生此错误。</span><span class="yiyi-st" id="yiyi-81">此错误是<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>的子类型。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-82"><span class="versionmodified">版本3.3中的新功能:</span>此错误以前是<a class="reference internal" href="exceptions.html#IOError" title="IOError"><code class="xref py py-exc docutils literal"><span class="pre">IOError</span></code></a>的子类型,现在是<a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-exc docutils literal"><span class="pre">OSError</span></code></a>的别名。</span></p></div></dd></dl><p><span class="yiyi-st" id="yiyi-83"><a class="reference internal" href="#module-signal" title="signal: Set handlers for asynchronous events."><code class="xref py py-mod docutils literal"><span class="pre">signal</span></code></a>模块定义以下功能:</span></p><dl class="function"><dt id="signal.alarm"><span class="yiyi-st" id="yiyi-84"> <code class="descclassname">signal.</code><code class="descname">alarm</code><span class="sig-paren">(</span><em>time</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-85">如果<em>时间</em>不为零,则此功能请求在<em>时间</em>秒内将<code class="xref py py-const docutils literal"><span class="pre">SIGALRM</span></code>信号发送到过程。</span><span class="yiyi-st" id="yiyi-86">任何先前安排的警报被取消(只能在任何时间安排一个警报)。</span><span class="yiyi-st" id="yiyi-87">返回的值是之前设置的任何警报发送之前的秒数。</span><span class="yiyi-st" id="yiyi-88">如果<em>时间</em>为零,则不计划报警,并取消任何预设报警。</span><span class="yiyi-st" id="yiyi-89">如果返回值为零,则当前未调度报警。</span><span class="yiyi-st" id="yiyi-90">(参见Unix手册页<em class="manpage">alarm(2)</em>。)</span><span class="yiyi-st" id="yiyi-91">可用性:Unix。</span></p></dd></dl><dl class="function"><dt id="signal.getsignal"><span class="yiyi-st" id="yiyi-92"> <code class="descclassname">signal.</code><code class="descname">getsignal</code><span class="sig-paren">(</span><em>signalnum</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-93">返回信号<em>signalnum</em>的当前信号处理程序。</span><span class="yiyi-st" id="yiyi-94">返回的值可以是可调用的Python对象或特殊值<a class="reference internal" href="#signal.SIG_IGN" title="signal.SIG_IGN"><code class="xref py py-const docutils literal"><span class="pre">signal.SIG_IGN</span></code></a>,<a class="reference internal" href="#signal.SIG_DFL" title="signal.SIG_DFL"><code class="xref py py-const docutils literal"><span class="pre">signal.SIG_DFL</span></code></a>或<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a>之一。</span><span class="yiyi-st" id="yiyi-95">这里,<a class="reference internal" href="#signal.SIG_IGN" title="signal.SIG_IGN"><code class="xref py py-const docutils literal"><span class="pre">signal.SIG_IGN</span></code></a>意味着信号先前被忽略,<a class="reference internal" href="#signal.SIG_DFL" title="signal.SIG_DFL"><code class="xref py py-const docutils literal"><span class="pre">signal.SIG_DFL</span></code></a>意味着处理信号的默认方式是先前使用的,并且<code class="docutils literal"><span class="pre">None</span></code></span></p></dd></dl><dl class="function"><dt id="signal.pause"><span class="yiyi-st" id="yiyi-96"> <code class="descclassname">signal.</code><code class="descname">pause</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-97">使该过程睡眠直到接收到信号;那么将调用适当的处理程序。</span><span class="yiyi-st" id="yiyi-98">不返回任何内容。</span><span class="yiyi-st" id="yiyi-99">不在Windows上。</span><span class="yiyi-st" id="yiyi-100">(请参见Unix手册页<em class="manpage">信号(2)</em>。)</span></p><p><span class="yiyi-st" id="yiyi-101">另见<a class="reference internal" href="#signal.sigwait" title="signal.sigwait"><code class="xref py py-func docutils literal"><span class="pre">sigwait()</span></code></a>,<a class="reference internal" href="#signal.sigwaitinfo" title="signal.sigwaitinfo"><code class="xref py py-func docutils literal"><span class="pre">sigwaitinfo()</span></code></a>,<a class="reference internal" href="#signal.sigtimedwait" title="signal.sigtimedwait"><code class="xref py py-func docutils literal"><span class="pre">sigtimedwait()</span></code></a>和<a class="reference internal" href="#signal.sigpending" title="signal.sigpending"><code class="xref py py-func docutils literal"><span class="pre">sigpending()</span></code></a>。</span></p></dd></dl><dl class="function"><dt id="signal.pthread_kill"><span class="yiyi-st" id="yiyi-102"> <code class="descclassname">signal.</code><code class="descname">pthread_kill</code><span class="sig-paren">(</span><em>thread_id</em>, <em>signalnum</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-103">将信号<em>signalnum</em>发送到线程<em>thread_id</em>,这是与调用者相同的进程中的另一个线程。</span><span class="yiyi-st" id="yiyi-104">目标线程可以执行任何代码(Python或不是)。</span><span class="yiyi-st" id="yiyi-105">但是,如果目标线程正在执行Python解释器,则Python信号处理程序将由主线程执行<a class="reference internal" href="#signals-and-threads"><span>executed by the main thread</span></a></span><span class="yiyi-st" id="yiyi-106">因此,向特定Python线程发送信号的唯一一点是强制运行系统调用失败,并显示<a class="reference internal" href="exceptions.html#InterruptedError" title="InterruptedError"><code class="xref py py-exc docutils literal"><span class="pre">InterruptedError</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-107">使用<a class="reference internal" href="threading.html#threading.get_ident" title="threading.get_ident"><code class="xref py py-func docutils literal"><span class="pre">threading.get_ident()</span></code></a>或<a class="reference internal" href="threading.html#threading.Thread" title="threading.Thread"><code class="xref py py-class docutils literal"><span class="pre">threading.Thread</span></code></a>对象的<a class="reference internal" href="threading.html#threading.Thread.ident" title="threading.Thread.ident"><code class="xref py py-attr docutils literal"><span class="pre">ident</span></code></a>属性为<em>thread_id</em> 。</span></p><p><span class="yiyi-st" id="yiyi-108">如果<em>signalnum</em>为0,则不发送信号,但仍然执行错误检查;这可以用于检查目标线程是否仍在运行。</span></p><p><span class="yiyi-st" id="yiyi-109">可用性:Unix(有关详细信息,请参见手册页<em class="manpage">pthread_kill(3)</em>)。</span></p><p><span class="yiyi-st" id="yiyi-110">另请参见<a class="reference internal" href="os.html#os.kill" title="os.kill"><code class="xref py py-func docutils literal"><span class="pre">os.kill()</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-111"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="function"><dt id="signal.pthread_sigmask"><span class="yiyi-st" id="yiyi-112"> <code class="descclassname">signal.</code><code class="descname">pthread_sigmask</code><span class="sig-paren">(</span><em>how</em>, <em>mask</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-113">获取和/或更改调用线程的信号掩码。</span><span class="yiyi-st" id="yiyi-114">信号掩码是当前为呼叫者阻止其传递的一组信号。</span><span class="yiyi-st" id="yiyi-115">将旧的信号掩码作为一组信号返回。</span></p><p><span class="yiyi-st" id="yiyi-116">调用的行为取决于<em>如何</em>的值,如下所示。</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-117"><a class="reference internal" href="#signal.SIG_BLOCK" title="signal.SIG_BLOCK"><code class="xref py py-data docutils literal"><span class="pre">SIG_BLOCK</span></code></a>:阻塞信号集合是当前集合的共用体和<em>掩码</em>参数。</span></li><li><span class="yiyi-st" id="yiyi-118"><a class="reference internal" href="#signal.SIG_UNBLOCK" title="signal.SIG_UNBLOCK"><code class="xref py py-data docutils literal"><span class="pre">SIG_UNBLOCK</span></code></a>:<em>掩码</em>中的信号从当前阻塞信号集中删除。</span><span class="yiyi-st" id="yiyi-119">允许尝试解除未阻塞的信号。</span></li><li><span class="yiyi-st" id="yiyi-120"><a class="reference internal" href="#signal.SIG_SETMASK" title="signal.SIG_SETMASK"><code class="xref py py-data docutils literal"><span class="pre">SIG_SETMASK</span></code></a>:阻塞信号集设置为<em>掩码</em>参数。</span></li></ul><p><span class="yiyi-st" id="yiyi-121"><em>掩码</em>是一组信号号码(例如,</span><span class="yiyi-st" id="yiyi-122">{<code class="xref py py-const docutils literal"><span class="pre">signal.SIGINT</span></code>,<code class="xref py py-const docutils literal"><span class="pre">signal.SIGTERM</span></code>})。</span><span class="yiyi-st" id="yiyi-123">使用<code class="docutils literal"><span class="pre">范围(1,</span> <span class="pre">signal.NSIG)</span></code>获取包含所有信号的完整掩码。</span></p><p><span class="yiyi-st" id="yiyi-124">例如,<code class="docutils literal"><span class="pre">signal.pthread_sigmask(signal.SIG_BLOCK,</span> <span class="pre">[])</span></code>读取调用线程的信号掩码。</span></p><p><span class="yiyi-st" id="yiyi-125">可用性:Unix。</span><span class="yiyi-st" id="yiyi-126">有关更多信息,请参阅手册页<em class="manpage">sigprocmask(3)</em>和<em class="manpage">pthread_sigmask(3)</em></span></p><p><span class="yiyi-st" id="yiyi-127">另请参见<a class="reference internal" href="#signal.pause" title="signal.pause"><code class="xref py py-func docutils literal"><span class="pre">pause()</span></code></a>,<a class="reference internal" href="#signal.sigpending" title="signal.sigpending"><code class="xref py py-func docutils literal"><span class="pre">sigpending()</span></code></a>和<a class="reference internal" href="#signal.sigwait" title="signal.sigwait"><code class="xref py py-func docutils literal"><span class="pre">sigwait()</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-128"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="function"><dt id="signal.setitimer"><span class="yiyi-st" id="yiyi-129"> <code class="descclassname">signal.</code><code class="descname">setitimer</code><span class="sig-paren">(</span><em>which</em>, <em>seconds</em><span class="optional">[</span>, <em>interval</em><span class="optional">]</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-130">设置由<em>指定的给定间隔定时器(<a class="reference internal" href="#signal.ITIMER_REAL" title="signal.ITIMER_REAL"><code class="xref py py-const docutils literal"><span class="pre">signal.ITIMER_REAL</span></code></a>,<a class="reference internal" href="#signal.ITIMER_VIRTUAL" title="signal.ITIMER_VIRTUAL"><code class="xref py py-const docutils literal"><span class="pre">signal.ITIMER_VIRTUAL</span></code></a>或<a class="reference internal" href="#signal.ITIMER_PROF" title="signal.ITIMER_PROF"><code class="xref py py-const docutils literal"><span class="pre">signal.ITIMER_PROF</span></code></a>在<em>秒</em>(接受浮动,不同于<a class="reference internal" href="#signal.alarm" title="signal.alarm"><code class="xref py py-func docutils literal"><span class="pre">alarm()</span></code></a>)之后,每隔<em>间隔</em></em></span><span class="yiyi-st" id="yiyi-131">由<em>指定的间隔定时器</em>可以通过将秒设置为零来清除。</span></p><p><span class="yiyi-st" id="yiyi-132">当间隔定时器触发时,向处理发送信号。</span><span class="yiyi-st" id="yiyi-133">The signal sent is dependent on the timer being used; <a class="reference internal" href="#signal.ITIMER_REAL" title="signal.ITIMER_REAL"><code class="xref py py-const docutils literal"><span class="pre">signal.ITIMER_REAL</span></code></a> will deliver <code class="xref py py-const docutils literal"><span class="pre">SIGALRM</span></code>, <a class="reference internal" href="#signal.ITIMER_VIRTUAL" title="signal.ITIMER_VIRTUAL"><code class="xref py py-const docutils literal"><span class="pre">signal.ITIMER_VIRTUAL</span></code></a> sends <code class="xref py py-const docutils literal"><span class="pre">SIGVTALRM</span></code>, and <a class="reference internal" href="#signal.ITIMER_PROF" title="signal.ITIMER_PROF"><code class="xref py py-const docutils literal"><span class="pre">signal.ITIMER_PROF</span></code></a> will deliver <code class="xref py py-const docutils literal"><span class="pre">SIGPROF</span></code>.</span></p><p><span class="yiyi-st" id="yiyi-134">旧值作为元组返回:(delay,interval)。</span></p><p><span class="yiyi-st" id="yiyi-135">尝试传递无效间隔定时器将导致<a class="reference internal" href="#signal.ItimerError" title="signal.ItimerError"><code class="xref py py-exc docutils literal"><span class="pre">ItimerError</span></code></a>。</span><span class="yiyi-st" id="yiyi-136">可用性:Unix。</span></p></dd></dl><dl class="function"><dt id="signal.getitimer"><span class="yiyi-st" id="yiyi-137"> <code class="descclassname">signal.</code><code class="descname">getitimer</code><span class="sig-paren">(</span><em>which</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-138">返回由<em>指定的给定间隔定时器的当前值,其中</em>。</span><span class="yiyi-st" id="yiyi-139">可用性:Unix。</span></p></dd></dl><dl class="function"><dt id="signal.set_wakeup_fd"><span class="yiyi-st" id="yiyi-140"> <code class="descclassname">signal.</code><code class="descname">set_wakeup_fd</code><span class="sig-paren">(</span><em>fd</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-141">将唤醒文件描述器设置为<em>fd</em>。</span><span class="yiyi-st" id="yiyi-142">当接收到信号时,信号号作为单字节写入fd。</span><span class="yiyi-st" id="yiyi-143">这可以由库用来唤醒轮询或选择呼叫,从而允许完全处理信号。</span></p><p><span class="yiyi-st" id="yiyi-144">返回旧的唤醒fd。</span><span class="yiyi-st" id="yiyi-145"><em>fd</em>必须是非阻塞的。</span><span class="yiyi-st" id="yiyi-146">在调用poll之前由库删除任何字节或再次选择。</span></p><p><span class="yiyi-st" id="yiyi-147">使用例如<code class="docutils literal"><span class="pre">struct.unpack('%uB'</span> <span class="pre">%</span> <span class="pre">len(data),</span> <span class="pre">data)</span> </code>来解码信号编号列表。</span></p><p><span class="yiyi-st" id="yiyi-148">当启用线程时,此函数只能从主线程调用;尝试从其他线程调用它将导致引发<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>异常。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-149"><span class="versionmodified">在3.5版本中更改:</span>在Windows上,此函数现在还支持套接字句柄。</span></p></div></dd></dl><dl class="function"><dt id="signal.siginterrupt"><span class="yiyi-st" id="yiyi-150"> <code class="descclassname">signal.</code><code class="descname">siginterrupt</code><span class="sig-paren">(</span><em>signalnum</em>, <em>flag</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-151">更改系统呼叫重新启动行为:如果<em>标志</em>为<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal"><span class="pre">False</span></code></a>,系统呼叫将在由信号<em>signalnum</em>中断时重新启动,否则系统呼叫将中断。</span><span class="yiyi-st" id="yiyi-152">不返回任何内容。</span><span class="yiyi-st" id="yiyi-153">可用性:Unix(有关详细信息,请参见手册页<em class="manpage">siginterrupt(3)</em>)。</span></p><p><span class="yiyi-st" id="yiyi-154">请注意,使用<a class="reference internal" href="#module-signal" title="signal: Set handlers for asynchronous events."><code class="xref py py-func docutils literal"><span class="pre">signal()</span></code></a>安装信号处理程序将通过隐式调用<code class="xref c c-func docutils literal"><span class="pre">siginterrupt()</span></code>将真实的<em>标志</em>给定的信号。</span></p></dd></dl><dl class="function"><dt id="signal.signal"><span class="yiyi-st" id="yiyi-155"> <code class="descclassname">signal.</code><code class="descname">signal</code><span class="sig-paren">(</span><em>signalnum</em>, <em>handler</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-156">将信号<em>signalnum</em>的处理程序设置为<em>处理程序</em>。</span><span class="yiyi-st" id="yiyi-157"><em>处理程序</em>可以是具有两个参数(见下文)或特殊值<a class="reference internal" href="#signal.SIG_IGN" title="signal.SIG_IGN"><code class="xref py py-const docutils literal"><span class="pre">signal.SIG_IGN</span></code></a>或<a class="reference internal" href="#signal.SIG_DFL" title="signal.SIG_DFL"><code class="xref py py-const docutils literal"><span class="pre">signal.SIG_DFL</span></code></a>的可调用Python对象。</span><span class="yiyi-st" id="yiyi-158">将返回上一个信号处理程序(请参阅上面的<a class="reference internal" href="#signal.getsignal" title="signal.getsignal"><code class="xref py py-func docutils literal"><span class="pre">getsignal()</span></code></a>的描述)。</span><span class="yiyi-st" id="yiyi-159">(请参见Unix手册页<em class="manpage">信号(2)</em>。)</span></p><p><span class="yiyi-st" id="yiyi-160">当启用线程时,此函数只能从主线程调用;尝试从其他线程调用它将导致引发<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>异常。</span></p><p><span class="yiyi-st" id="yiyi-161">使用两个参数调用<em>处理程序</em>:信号编号和当前堆栈帧(<code class="docutils literal"><span class="pre">None</span></code>或帧对象;有关帧对象的描述,请参阅<a class="reference internal" href="../reference/datamodel.html#frame-objects"><span>description in the type hierarchy</span></a>中,或查看<a class="reference internal" href="inspect.html#module-inspect" title="inspect: Extract information and source code from live objects."><code class="xref py py-mod docutils literal"><span class="pre">inspect</span></code></a>模块中的属性说明)。</span></p><p><span class="yiyi-st" id="yiyi-162">在Windows上, <a class="reference internal" href="#module-signal" title="signal: Set handlers for asynchronous events."><code class="xref py py-func docutils literal"><span class="pre">signal()</span></code></a> 只能调用 <code class="xref py py-const docutils literal"><span class="pre">SIGABRT</span></code>, <code class="xref py py-const docutils literal"><span class="pre">SIGFPE</span></code>, <code class="xref py py-const docutils literal"><span class="pre">SIGILL</span></code>, <code class="xref py py-const docutils literal"><span class="pre">SIGINT</span></code>, <code class="xref py py-const docutils literal"><span class="pre">SIGSEGV</span></code>, or <code class="xref py py-const docutils literal"><span class="pre">SIGTERM</span></code>. </span><span class="yiyi-st" id="yiyi-163">在任何其他情况下,将引发<a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a>。</span><span class="yiyi-st" id="yiyi-164">请注意,并非所有系统都定义相同的信号名称集;如果信号名称未定义为<code class="docutils literal"><span class="pre">SIG*</span></code>模块级常数,则会引发<a class="reference internal" href="exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal"><span class="pre">AttributeError</span></code></a>。</span></p></dd></dl><dl class="function"><dt id="signal.sigpending"><span class="yiyi-st" id="yiyi-165"> <code class="descclassname">signal.</code><code class="descname">sigpending</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-166">检查等待传递到调用线程的信号集合(即,在阻塞时已经产生的信号)。</span><span class="yiyi-st" id="yiyi-167">返回待处理信号的集合。</span></p><p><span class="yiyi-st" id="yiyi-168">可用性:Unix(有关详细信息,请参见手册页<em class="manpage">sigpending(2)</em>)。</span></p><p><span class="yiyi-st" id="yiyi-169">另请参见<a class="reference internal" href="#signal.pause" title="signal.pause"><code class="xref py py-func docutils literal"><span class="pre">pause()</span></code></a>,<a class="reference internal" href="#signal.pthread_sigmask" title="signal.pthread_sigmask"><code class="xref py py-func docutils literal"><span class="pre">pthread_sigmask()</span></code></a>和<a class="reference internal" href="#signal.sigwait" title="signal.sigwait"><code class="xref py py-func docutils literal"><span class="pre">sigwait()</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-170"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="function"><dt id="signal.sigwait"><span class="yiyi-st" id="yiyi-171"> <code class="descclassname">signal.</code><code class="descname">sigwait</code><span class="sig-paren">(</span><em>sigset</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-172">挂起调用线程的执行,直到发送信号集<em>sigset</em>中指定的信号之一。</span><span class="yiyi-st" id="yiyi-173">该函数接受信号(将其从待处理的信号列表中删除),并返回信号编号。</span></p><p><span class="yiyi-st" id="yiyi-174">可用性:Unix(有关详细信息,请参见手册页<em class="manpage">sigwait(3)</em>)。</span></p><p><span class="yiyi-st" id="yiyi-175">另请参见<a class="reference internal" href="#signal.pause" title="signal.pause"><code class="xref py py-func docutils literal"><span class="pre">pause()</span></code></a>,<a class="reference internal" href="#signal.pthread_sigmask" title="signal.pthread_sigmask"><code class="xref py py-func docutils literal"><span class="pre">pthread_sigmask()</span></code></a>,<a class="reference internal" href="#signal.sigpending" title="signal.sigpending"><code class="xref py py-func docutils literal"><span class="pre">sigpending()</span></code></a>,<a class="reference internal" href="#signal.sigwaitinfo" title="signal.sigwaitinfo"><code class="xref py py-func docutils literal"><span class="pre">sigwaitinfo()</span></code></a>和<a class="reference internal" href="#signal.sigtimedwait" title="signal.sigtimedwait"><code class="xref py py-func docutils literal"><span class="pre">sigtimedwait()</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-176"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div></dd></dl><dl class="function"><dt id="signal.sigwaitinfo"><span class="yiyi-st" id="yiyi-177"> <code class="descclassname">signal.</code><code class="descname">sigwaitinfo</code><span class="sig-paren">(</span><em>sigset</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-178">挂起调用线程的执行,直到发送信号集<em>sigset</em>中指定的信号之一。</span><span class="yiyi-st" id="yiyi-179">该函数接受信号并将其从待处理的信号列表中删除。</span><span class="yiyi-st" id="yiyi-180">如果<em>sigset</em>中的信号之一已经等待调用线程,则函数将立即返回有关该信号的信息。</span><span class="yiyi-st" id="yiyi-181">对于传递的信号,不调用信号处理程序。</span><span class="yiyi-st" id="yiyi-182">如果函数被不在<em>sigset</em>中的信号中断,则函数引发<a class="reference internal" href="exceptions.html#InterruptedError" title="InterruptedError"><code class="xref py py-exc docutils literal"><span class="pre">InterruptedError</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-183">返回值是表示包含在<code class="xref c c-type docutils literal"><span class="pre">siginfo_t</span></code>结构中的数据的对象,即:<code class="xref py py-attr docutils literal"><span class="pre">si_signo</span></code>,<code class="xref py py-attr docutils literal"><span class="pre">si_code</span></code>,<code class="xref py py-attr docutils literal"><span class="pre">si_errno</span></code> ,<code class="xref py py-attr docutils literal"><span class="pre">si_pid</span></code>,<code class="xref py py-attr docutils literal"><span class="pre">si_uid</span></code>,<code class="xref py py-attr docutils literal"><span class="pre">si_status</span></code>,<code class="xref py py-attr docutils literal"><span class="pre">si_band</span></code>。</span></p><p><span class="yiyi-st" id="yiyi-184">可用性:Unix(有关详细信息,请参见手册页<em class="manpage">sigwaitinfo(2)</em>)。</span></p><p><span class="yiyi-st" id="yiyi-185">另请参见<a class="reference internal" href="#signal.pause" title="signal.pause"><code class="xref py py-func docutils literal"><span class="pre">pause()</span></code></a>,<a class="reference internal" href="#signal.sigwait" title="signal.sigwait"><code class="xref py py-func docutils literal"><span class="pre">sigwait()</span></code></a>和<a class="reference internal" href="#signal.sigtimedwait" title="signal.sigtimedwait"><code class="xref py py-func docutils literal"><span class="pre">sigtimedwait()</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-186"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-187"><span class="versionmodified">在版本3.5中更改:</span>如果信号不在<em>sigset</em>中,信号处理程序不引发异常,则此函数现在重试(请参阅<span class="target" id="index-0"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0475"><strong>PEP 475</strong></a>的理由)。</span></p></div></dd></dl><dl class="function"><dt id="signal.sigtimedwait"><span class="yiyi-st" id="yiyi-188"> <code class="descclassname">signal.</code><code class="descname">sigtimedwait</code><span class="sig-paren">(</span><em>sigset</em>, <em>timeout</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-189">像<a class="reference internal" href="#signal.sigwaitinfo" title="signal.sigwaitinfo"><code class="xref py py-func docutils literal"><span class="pre">sigwaitinfo()</span></code></a>,但是需要一个额外的<em>超时</em>参数指定超时。</span><span class="yiyi-st" id="yiyi-190">如果<em>超时</em>被指定为<code class="xref py py-const docutils literal"><span class="pre">0</span></code>,则执行轮询。</span><span class="yiyi-st" id="yiyi-191">如果发生超时,则返回<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal"><span class="pre">None</span></code></a>。</span></p><p><span class="yiyi-st" id="yiyi-192">可用性:Unix(有关详细信息,请参见手册页<em class="manpage">sigtimedwait(2)</em>)。</span></p><p><span class="yiyi-st" id="yiyi-193">另请参见<a class="reference internal" href="#signal.pause" title="signal.pause"><code class="xref py py-func docutils literal"><span class="pre">pause()</span></code></a>,<a class="reference internal" href="#signal.sigwait" title="signal.sigwait"><code class="xref py py-func docutils literal"><span class="pre">sigwait()</span></code></a>和<a class="reference internal" href="#signal.sigwaitinfo" title="signal.sigwaitinfo"><code class="xref py py-func docutils literal"><span class="pre">sigwaitinfo()</span></code></a>。</span></p><div class="versionadded"><p><span class="yiyi-st" id="yiyi-194"><span class="versionmodified">版本3.3中的新功能。</span></span></p></div><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-195"><span class="versionmodified">在版本3.5中更改:</span>如果被不在<em>sigset</em>中的信号中断,并且信号处理程序未引发,则重新计算的<em>超时</em>异常(有关理由,请参见<span class="target" id="index-1"></span> <a class="pep reference external" href="https://www.python.org/dev/peps/pep-0475"><strong>PEP 475</strong></a>)。</span></p></div></dd></dl></div><div class="section" id="example"><h2><span class="yiyi-st" id="yiyi-196">18.8.3. </span><span class="yiyi-st" id="yiyi-197">Example</span></h2><p><span class="yiyi-st" id="yiyi-198">这里是一个最小的示例程序。</span><span class="yiyi-st" id="yiyi-199">它使用<a class="reference internal" href="#signal.alarm" title="signal.alarm"><code class="xref py py-func docutils literal"><span class="pre">alarm()</span></code></a>函数来限制等待打开文件所花费的时间;如果文件用于可能无法打开的串行设备,这通常会导致<a class="reference internal" href="os.html#os.open" title="os.open"><code class="xref py py-func docutils literal"><span class="pre">os.open()</span></code></a>无限期挂起,这是非常有用的。</span><span class="yiyi-st" id="yiyi-200">解决方法是在打开文件之前设置5秒报警;如果操作花费太长时间,将发送报警信号,并且处理程序引发异常。</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">signal</span><span class="o">,</span> <span class="nn">os</span>
|
||
|
||
<span class="k">def</span> <span class="nf">handler</span><span class="p">(</span><span class="n">signum</span><span class="p">,</span> <span class="n">frame</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Signal handler called with signal'</span><span class="p">,</span> <span class="n">signum</span><span class="p">)</span>
|
||
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="s2">"Couldn't open device!"</span><span class="p">)</span>
|
||
|
||
<span class="c1"># Set the signal handler and a 5-second alarm</span>
|
||
<span class="n">signal</span><span class="o">.</span><span class="n">signal</span><span class="p">(</span><span class="n">signal</span><span class="o">.</span><span class="n">SIGALRM</span><span class="p">,</span> <span class="n">handler</span><span class="p">)</span>
|
||
<span class="n">signal</span><span class="o">.</span><span class="n">alarm</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
|
||
|
||
<span class="c1"># This open() may hang indefinitely</span>
|
||
<span class="n">fd</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">'/dev/ttyS0'</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">O_RDWR</span><span class="p">)</span>
|
||
|
||
<span class="n">signal</span><span class="o">.</span><span class="n">alarm</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># Disable the alarm</span>
|
||
</code></pre></div></div></div> |