std::signal
| 在头文件 <csignal>
|
||
/*signal-handler*/* signal( int sig, /*signal-handler*/* handler );
|
中定义 (1) | |
extern "C" using /*signal-handler*/ = void(int);
|
(2) | (*仅供说明) |
更改信号 sig 的处理方式。根据 handler 的值,信号可以被忽略、设为默认处理,或由用户定义的函数以 (*handler)(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 (异步信号),则在以下情况下行为未定义:
|
(until C++17) |
|
纯无锁原子操作 是指调用来自 <atomic> 或 <stdatomic.h> (since C++23) 的函数 f ,且满足以下条件之一:
若任何信号处理器执行以下任一操作,则行为未定义:
|
(since 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++23 标准 (ISO/IEC 14882:2024):
-
- 17.13.5 信号处理程序 [support.signal]
- C++20 标准 (ISO/IEC 14882:2020):
-
- 17.13.5 信号处理程序 [support.signal]
- C++17 标准 (ISO/IEC 14882:2017):
-
- 21.10.4 信号处理程序 [support.signal]
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| 缺陷报告 | 适用范围 | 发布时行为 | 正确行为 |
|---|---|---|---|
| LWG 3756 | C++17 | 未明确说明 std::atomic_flag 是否具有信号安全性 | 具有信号安全性 |
参阅
|
为特定信号运行信号处理程序
(函数) |
|
|
(C++11)
|
同一线程内线程与信号处理程序之间的栅栏
(函数) |
|
C 文档
关于
signal
|
|