252 lines
25 KiB
HTML
252 lines
25 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>std::signal</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_utility_program_signal skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading"><span style="font-size:0.7em; line-height:130%">std::</span>signal</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-utility.html">utility</a>‎ | <a href="cpp-utility-program.html">program</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dsc-header">
|
|
<td>
|
|
<div>定义于头文件 <code><a href="cpp-header-csignal.html"><csignal></a></code></div>
|
|
</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="coMULTI">/*signal-handler*/</span><span class="sy2">*</span> signal<span class="br0">(</span><span class="kw4">int</span> sig, <span class="coMULTI">/*signal-handler*/</span><span class="sy2">*</span> handler<span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td>(1)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl">
|
|
<td>
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">extern</span> <span class="st0">"C"</span> <span class="kw1">using</span> <span class="coMULTI">/*signal-handler*/</span> <span class="sy1">=</span> <span class="kw4">void</span><span class="br0">(</span><span class="kw4">int</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 仅为说明</span></span></div>
|
|
</td>
|
|
<td>(2)</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<p>为信号 <code>sig</code> 设置处理函数。可设置信号处理函数以令默认处理发生、信号被忽略或用户定义函数得到调用。</p>
|
|
<p>当信号处理函数被设为函数,且信号发生时,在信号处理函数开始之前是否立即执行 <span class="t-c"><span class="mw-geshi cpp source-cpp">std<span class="sy4">::</span><span class="me2">signal</span><span class="br0">(</span>sig, <a href="cpp-utility-program-SIG_strategies.html"><span class="kw978">SIG_DFL</span></a><span class="br0">)</span></span></span> 是实现定义的。而且实现可以避免某些信号的实现定义集在信号处理函数运行时出现。</p>
|
|
<p>对于某些信号,程序开始时是否调用 <span class="t-c"><span class="mw-geshi cpp source-cpp">std<span class="sy4">::</span><span class="me2">signal</span><span class="br0">(</span>sig, <a href="cpp-utility-program-SIG_strategies.html"><span class="kw979">SIG_IGN</span></a><span class="br0">)</span></span></span> 所实现定义的。对于剩余函数,实现必须调用 <span class="t-c"><span class="mw-geshi cpp source-cpp">std<span class="sy4">::</span><span class="me2">signal</span><span class="br0">(</span>sig, <a href="cpp-utility-program-SIG_strategies.html"><span class="kw978">SIG_DFL</span></a><span class="br0">)</span></span></span> 。</p>
|
|
<p>(注意: POSIX 引入了 <a rel="nofollow" class="external text" href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html">sigaction</a> 以标准化这些实现定义行为)</p>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E6.95.B0">参数</span></h3>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td>sig</td>
|
|
<td>-</td>
|
|
<td>要设置信号处理函数的信号。它可以是实现定义值或下例值之一:
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-utility-program-SIG_types.html"><span class="t-lines"><span>SIGABRT</span><span>SIGFPE</span><span>SIGILL</span><span>SIGINT</span><span>SIGSEGV</span><span>SIGTERM</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>定义信号类型<br />
|
|
<span class="t-mark">(宏常量)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p><br /></p>
|
|
</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td>handler</td>
|
|
<td>-</td>
|
|
<td>信号处理函数。这必须是下列之一:
|
|
<ul>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-SIG_strategies.html">SIG_DFL</a></span> 宏。信号处理函数被设为默认信号处理函数。</li>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-SIG_strategies.html">SIG_IGN</a></span> 宏。忽略信号。</li>
|
|
<li>指向函数指针。函数签名必须等价于如下:</li>
|
|
</ul>
|
|
<table class="t-dcl-begin">
|
|
<tbody>
|
|
<tr class="t-dcl">
|
|
<td class="t-dcl-nopad">
|
|
<div><span class="mw-geshi cpp source-cpp"><span class="kw4">extern</span> <span class="st0">"C"</span> <span class="kw4">void</span> fun<span class="br0">(</span><span class="kw4">int</span> sig<span class="br0">)</span><span class="sy4">;</span></span></div>
|
|
</td>
|
|
<td class="t-dcl-nopad"></td>
|
|
<td class="t-dcl-nopad"></td>
|
|
</tr>
|
|
<tr class="t-dcl-sep">
|
|
<td></td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.BF.94.E5.9B.9E.E5.80.BC">返回值</span></h3>
|
|
<p>成功时为先前的信号处理函数,失败时为 <span class="t-lc"><a href="cpp-utility-program-SIG_ERR.html">SIG_ERR</a></span> (某些实现上能禁用设置信号处理函数)。</p>
|
|
<h3><span class="mw-headline" id=".E4.BF.A1.E5.8F.B7.E5.A4.84.E7.90.86.E5.87.BD.E6.95.B0">信号处理函数</span></h3>
|
|
<p>下列限制被加诸被安装为信号处理函数的用户定义函数。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx17">
|
|
<td>
|
|
<p>若信号处理函数不作为 <span class="t-lc"><a href="cpp-utility-program-abort.html">std::abort</a></span> 或 <span class="t-lc"><a href="cpp-utility-program-raise.html">std::raise</a></span> (异步信号)的结果调用,则行为未定义,若</p>
|
|
<ul>
|
|
<li>信号处理函数调用任何标准库中的函数,除了</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-abort.html">std::abort</a></span></li>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-_Exit.html">std::_Exit</a></span></li>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-quick_exit.html">std::quick_exit</a></span></li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">std<span class="sy4">::</span><span class="me2">signal</span></span></span> ,以当前处理的信号的数字为首参数(异步处理函数能重注册其自身,但不能注册其他函数)。</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<ul>
|
|
<li>信号处理函数涉及任何拥有静态或线程局域<span class="t-mark-rev t-since-cxx11">(C++11 起)</span>存储期的对象,且其类型不是 <span class="t-lc"><a href="cpp-atomic-atomic.html">std::atomic</a></span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">volatile</span> <a href="cpp-utility-program-sig_atomic_t.html"><span class="kw977">std::<span class="me2">sig_atomic_t</span></span></a></span></span>.</li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>若任何信号处理函数进行任何下列操作,则行为未定义:</p>
|
|
<ul>
|
|
<li>调用任何库函数,除了下列<i>信号安全</i>函数(注意,尤其是动态分配函数不是信号安全的):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li><span class="t-lc"><a href="cpp-atomic-atomic.html">std::atomic</a></span> 的成员函数和来自 <a href="cpp-atomic.html"><atomic></a> 的非成员函数,若它们所操作的原子类型是免锁的。函数 <span class="t-lc"><a href="cpp-atomic-atomic_is_lock_free.html">std::atomic_is_lock_free</a></span> 及 <span class="t-lc"><a href="cpp-atomic-atomic-is_lock_free.html">std::atomic::is_lock_free</a></span> 对所有原子类型信号安全。</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp">std<span class="sy4">::</span><span class="me2">signal</span></span></span> ,以当前处理的信号的数字为首参数(异步处理函数能重注册其自身,但不能注册其他函数)。</li>
|
|
<li><span class="t-lc"><a href="cpp-types-numeric_limits.html">std::numeric_limits</a></span> 的函数</li>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-_Exit.html">std::_Exit</a></span></li>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-abort.html">std::abort</a></span></li>
|
|
<li><span class="t-lc"><a href="cpp-utility-program-quick_exit.html">std::quick_exit</a></span></li>
|
|
<li><span class="t-lc"><a href="cpp-utility-initializer_list.html">std::initializer_list</a></span> 的成员函数及 <span class="t-lc"><a href="cpp-iterator-begin.html">std::begin</a></span> 与 <span class="t-lc"><a href="cpp-iterator-end.html">std::end</a></span> 的 <code>std::initializer_list</code> 重载</li>
|
|
<li><span class="t-lc"><a href="cpp-utility-forward.html">std::forward</a></span> 、 <span class="t-lc">std::move</span> 、 <span class="t-lc"><a href="cpp-utility-move_if_noexcept.html">std::move_if_noexcept</a></span></li>
|
|
<li>所有来自 <a href="cpp-types.html#.E7.B1.BB.E5.9E.8B.E7.89.B9.E6.80.A7"><type_traits></a> 的函数</li>
|
|
<li><span class="t-lc"><a href="cpp-string-byte-memcpy.html">std::memcpy</a></span> 与 <span class="t-lc"><a href="cpp-string-byte-memmove.html">std::memmove</a></span></li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<ul>
|
|
<li>访问拥有线程存储期的对象</li>
|
|
<li><a href="cpp-language-dynamic_cast.html"><tt>dynamic_cast</tt></a> 表达式</li>
|
|
<li><a href="cpp-language-throw.html"><tt>throw</tt></a> 表达式</li>
|
|
<li>进入 <a href="cpp-language-try_catch.html"><tt>try</tt></a> 块,包含<a href="cpp-language-function-try-block.html"><tt>函数 try 块</tt></a></li>
|
|
<li>初始化进行<a href="cpp-language-initialization.html#.E9.9D.9E.E5.B1.80.E9.83.A8.E5.8F.98.E9.87.8F">动态非局部初始化</a>的静态变量(包含延迟直至首次 ODR 使用者)</li>
|
|
<li>等待任何有静态存储期变量的初始化完成,由于另一线程共时初始化之</li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>若在处理 <span class="t-lc"><a href="cpp-utility-program-SIG_types.html">SIGFPE</a></span> 、 <span class="t-lc"><a href="cpp-utility-program-SIG_types.html">SIGILL</a></span> 、 <span class="t-lc"><a href="cpp-utility-program-SIG_types.html">SIGSEGV</a></span> 或任何实现定义的指定计算性异常的其他信号时,用户定义函数返回,则行为未定义。</p>
|
|
<p>若信号处理函数作为 <span class="t-lc"><a href="cpp-utility-program-abort.html">std::abort</a></span> 或 <span class="t-lc"><a href="cpp-utility-program-raise.html">std::raise</a></span> (异步调用)的结果调用,则行为未定义,若信号处理函数调用 <span class="t-lc"><a href="cpp-utility-program-raise.html">std::raise</a></span> 。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx14">
|
|
<td>
|
|
<p>在信号处理函数入口,<a href="cpp-numeric-fenv.html">浮点环境</a>的状态和所有对象的值都是未指定的,除了</p>
|
|
<ul>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">volatile</span> <a href="cpp-utility-program-sig_atomic_t.html"><span class="kw977">std::<span class="me2">sig_atomic_t</span></span></a></span></span> 类型对象</li>
|
|
<li>无锁 <span class="t-lc"><a href="cpp-atomic-atomic.html">std::atomic</a></span> 类型对象<span class="t-mark-rev t-since-cxx11">(C++11 起)</span></li>
|
|
<li>通过 <span class="t-lc"><a href="cpp-atomic-atomic_signal_fence.html">std::atomic_signal_fence</a></span> 设为可见的副效应<span class="t-mark-rev t-since-cxx11">(C++11 起)</span></li>
|
|
</ul>
|
|
<p>从信号处理函数返回时,任何信号处理函数所修改的,非 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">volatile</span> <a href="cpp-utility-program-sig_atomic_t.html"><span class="kw977">std::<span class="me2">sig_atomic_t</span></span></a></span></span> 或免锁 <span class="t-lc"><a href="cpp-atomic-atomic.html">std::atomic</a></span> 对象的值是不确定的。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx14">(C++14 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx14">
|
|
<td>
|
|
<p>对函数 <code>signal()</code> 的调用<a href="cpp-atomic-memory_order.html">同步于</a>任何信号处理函数调用的结果。</p>
|
|
<p>若信号处理函数作为到 <span class="t-lc"><a href="cpp-utility-program-raise.html">std::raise</a></span> (同步)的调用结果执行,则处理函数的执行<i>后序于</i> <code>std::raise</code> 的调用并<i>先序于</i>从它返回,并与 <span class="t-lc">std::raise</span> 运行于同一线程。其他信号处理函数的执行对于程序其余部分是<i>无序</i>的,并且运行于未指定的线程。</p>
|
|
<p>若对同一 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">volatile</span> <a href="cpp-utility-program-sig_atomic_t.html"><span class="kw977">std::<span class="me2">sig_atomic_t</span></span></a></span></span> 类型对象的二次访问出现于同一线程,则它们不导致数据竞争,即使在信号处理函数中出现一或多次。 对每次信号处理函数调用,调用信号处理函数的线程所进行的求值可分为二组 A 与 B ,满足 B 中无求值<i>先发生于</i> A 中的求值,且这种 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">volatile</span> <a href="cpp-utility-program-sig_atomic_t.html"><span class="kw977">std::<span class="me2">sig_atomic_t</span></span></a></span></span> 对象的求值采用该值,如同 A 中所有求值<a href="cpp-atomic-memory_order.html">先发生于</a>信号函数的执行,且信号函数的求值<i>先发生于</i> B 中所有求值。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx14">(C++14 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E6.84.8F">注意</span></h3>
|
|
<p>POSIX 要求 <code>signal</code> 为线程安全,且<a rel="nofollow" class="external text" href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04">指定一个异步信号安全库函数的列表</a>,它们能从任何信号处理函数调用。</p>
|
|
<p>信号处理函数被期待拥有 <a href="cpp-language-language_linkage.html">C 链接</a>,而且通常只使用 C 与 C++ 的公共子集。拥有 C++ 链接的函数能否用作信号处理函数是实现定义的。</p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <csignal></span>
|
|
<span class="co2">#include <iostream></span>
|
|
|
|
<span class="kw1">namespace</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">volatile</span> <a href="cpp-utility-program-sig_atomic_t.html"><span class="kw977">std::<span class="me2">sig_atomic_t</span></span></a> gSignalStatus<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">void</span> signal_handler<span class="br0">(</span><span class="kw4">int</span> signal<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
gSignalStatus <span class="sy1">=</span> signal<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 安装信号处理函数</span>
|
|
std<span class="sy4">::</span><span class="me2">signal</span><span class="br0">(</span><a href="cpp-utility-program-SIG_types.html"><span class="kw984">SIGINT</span></a>, signal_handler<span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1757">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"SignalValue: "</span> <span class="sy1"><<</span> gSignalStatus <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1757">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"Sending signal "</span> <span class="sy1"><<</span> <a href="cpp-utility-program-SIG_types.html"><span class="kw984">SIGINT</span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<a href="cpp-utility-program-raise.html"><span class="kw976">std::<span class="me2">raise</span></span></a><span class="br0">(</span><a href="cpp-utility-program-SIG_types.html"><span class="kw984">SIGINT</span></a><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1757">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">"SignalValue: "</span> <span class="sy1"><<</span> gSignalStatus <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>可能的输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">SignalValue: 0
|
|
Sending signal 2
|
|
SignalValue: 2</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-utility-program-raise.html"><span class="t-lines"><span>raise</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>为特定信号运行信号处理函数<br />
|
|
<span class="t-mark">(函数)</span></td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-atomic-atomic_signal_fence.html"><span class="t-lines"><span>atomic_signal_fence</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>线程与执行于同一线程的信号处理函数间的栅栏<br />
|
|
<span class="t-mark">(函数)</span></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|