std::signal
定义于头文件 <csignal>
|
||
/*signal-handler*/* signal(int sig, /*signal-handler*/* handler); |
(1) | |
extern "C" using /*signal-handler*/ = void(int); // 仅为说明 |
(2) | |
为信号 sig
设置处理函数。可设置信号处理函数以令默认处理发生、信号被忽略或用户定义函数得到调用。
当信号处理函数被设为函数,且信号发生时,在信号处理函数开始之前是否立即执行 std::signal(sig, SIG_DFL) 是实现定义的。而且实现可以避免某些信号的实现定义集在信号处理函数运行时出现。
对于某些信号,程序开始时是否调用 std::signal(sig, SIG_IGN) 所实现定义的。对于剩余函数,实现必须调用 std::signal(sig, SIG_DFL) 。
(注意: POSIX 引入了 sigaction 以标准化这些实现定义行为)
参数
sig | - | 要设置信号处理函数的信号。它可以是实现定义值或下例值之一:
| ||||||
handler | - | 信号处理函数。这必须是下列之一:
|
返回值
成功时为先前的信号处理函数,失败时为 SIG_ERR (某些实现上能禁用设置信号处理函数)。
信号处理函数
下列限制被加诸被安装为信号处理函数的用户定义函数。
若信号处理函数不作为 std::abort 或 std::raise (异步信号)的结果调用,则行为未定义,若
|
(C++17 前) |
若任何信号处理函数进行任何下列操作,则行为未定义:
|
(C++17 起) |
若在处理 SIGFPE 、 SIGILL 、 SIGSEGV 或任何实现定义的指定计算性异常的其他信号时,用户定义函数返回,则行为未定义。
若信号处理函数作为 std::abort 或 std::raise (异步调用)的结果调用,则行为未定义,若信号处理函数调用 std::raise 。
在信号处理函数入口,浮点环境的状态和所有对象的值都是未指定的,除了
从信号处理函数返回时,任何信号处理函数所修改的,非 volatile std::sig_atomic_t 或免锁 std::atomic 对象的值是不确定的。 |
(C++14 前) |
对函数 若信号处理函数作为到 std::raise (同步)的调用结果执行,则处理函数的执行后序于 若对同一 volatile std::sig_atomic_t 类型对象的二次访问出现于同一线程,则它们不导致数据竞争,即使在信号处理函数中出现一或多次。 对每次信号处理函数调用,调用信号处理函数的线程所进行的求值可分为二组 A 与 B ,满足 B 中无求值先发生于 A 中的求值,且这种 volatile std::sig_atomic_t 对象的求值采用该值,如同 A 中所有求值先发生于信号函数的执行,且信号函数的求值先发生于 B 中所有求值。 |
(C++14 起) |
注意
POSIX 要求 signal
为线程安全,且指定一个异步信号安全库函数的列表,它们能从任何信号处理函数调用。
信号处理函数被期待拥有 C 链接,而且通常只使用 C 与 C++ 的公共子集。拥有 C++ 链接的函数能否用作信号处理函数是实现定义的。
示例
#include <csignal> #include <iostream> namespace { volatile std::sig_atomic_t gSignalStatus; } void signal_handler(int signal) { gSignalStatus = signal; } int main() { // 安装信号处理函数 std::signal(SIGINT, signal_handler); std::cout << "SignalValue: " << gSignalStatus << '\n'; std::cout << "Sending signal " << SIGINT << '\n'; std::raise(SIGINT); std::cout << "SignalValue: " << gSignalStatus << '\n'; }
可能的输出:
SignalValue: 0 Sending signal 2 SignalValue: 2
参阅
为特定信号运行信号处理函数 (函数) | |
(C++11) |
线程与执行于同一线程的信号处理函数间的栅栏 (函数) |