C++
编译器支持
自由(freestanding)与宿主(hosted)
语言
标准库
标准库头文件
具名要求
特性测试宏 (C++20)
语言支持库
概念库 (C++20)
诊断库
内存管理库
元编程库 (C++11)
通用工具库
容器库
迭代器库
范围库 (C++20)
算法库
字符串库
文本处理库
数值库
日期和时间库
输入/输出库
文件系统库 (C++17)
并发支持库 (C++11)
执行控制库 (C++26)
技术规范
符号索引
外部库
[编辑] 工具库
语言支持
类型支持(基本类型、RTTI)
库特性测试宏 (C++20)
程序工具
变参函数
initializer_list(C++11)
is_constant_evaluated(C++20)
is_within_lifetime(C++26)
source_location(C++20)
协程支持 (C++20)
契约支持 (C++26)
三路比较
three_way_comparablethree_way_comparable_with(C++20)(C++20)
strong_ordering(C++20)
weak_ordering(C++20)
partial_ordering(C++20)
common_comparison_category(C++20)
compare_three_way_result(C++20)
compare_three_way(C++20)
strong_order(C++20)
weak_order(C++20)
partial_order(C++20)
compare_strong_order_fallback(C++20)
compare_weak_order_fallback(C++20)
compare_partial_order_fallback(C++20)
is_eqis_ltis_lteq(C++20)(C++20)(C++20)
is_neqis_gtis_gteq(C++20)(C++20)(C++20)
通用工具
函数对象
位操作 (C++20)
bitset
hash(C++11)
关系运算符 (C++20 中弃用)
rel_ops::operator!=rel_ops::operator>
rel_ops::operator<=rel_ops::operator>=
整数比较函数
cmp_equalcmp_lesscmp_less_than(C++20)(C++20)(C++20)
cmp_not_equalcmp_greatercmp_greater_than(C++20)(C++20)(C++20)
in_range(C++20)
交换与类型操作
swap
ranges::swap(C++20)
exchange(C++14)
declval(C++11)
to_underlying(C++23)
forward(C++11)
forward_like(C++23)
move(C++11)
move_if_noexcept(C++11)
as_const(C++17)
常用词汇类型
pair
tuple(C++11)
optional(C++17)
any(C++17)
variant(C++17)
tuple_size(C++11)
tuple_element(C++11)
apply(C++17)
make_from_tuple(C++17)
expected(C++23)
[编辑] 程序支持实用程序
程序终止
abort
exit
quick_exit(C++11)
_Exit(C++11)
atexit
at_quick_exit(C++11)
EXIT_SUCCESSEXIT_FAILURE
不可达控制流
unreachable(C++23)
与环境通信
system
getenv
信号
signal
raise
sig_atomic_t
SIG_DFLSIG_IGN
SIG_ERR
信号类型
SIGABRTSIGFPESIGILL
SIGINTSIGSEGVSIGTERM
非局部跳转
setjmp
longjmp
类型
jmp_buf
[编辑]
定义于头文件
/* signal-handler */* signal( int sig, /* signal-handler */* handler );
(1)
extern "C" using /* signal-handler */ = void(int);
(2)
(仅作说明*)
改变信号 sig 的处理方式。根据 handler 的不同,信号可以被忽略,设置为默认处理,或者由用户定义函数处理。
当信号处理程序被设置为一个函数并且信号发生时,在信号处理程序开始之前是否立即执行 std::signal(sig, SIG_DFL) 是实现定义的。此外,实现可以在信号处理程序运行时阻止某些实现定义的信号集发生。
对于某些信号,实现可以在程序启动时调用 std::signal(sig, SIG_IGN)。对于其余信号,实现必须调用 std::signal(sig, SIG_DFL)。
(注意:POSIX 引入了 sigaction 来标准化这些实现定义的行为)
目录
1 参数
2 返回值
3 信号处理程序
4 注意
5 示例
6 引用
7 缺陷报告
8 参阅
[编辑] 参数
sig
-
要设置信号处理程序的信号。它可以是实现定义的值或以下值之一
SIGABRTSIGFPESIGILLSIGINTSIGSEGVSIGTERM
定义信号类型 (宏常量) [编辑]
处理程序
-
信号处理程序。这必须是以下之一 SIG_DFL 宏。信号处理程序设置为默认信号处理程序。 SIG_IGN 宏。信号被忽略。指向函数的指针。函数的签名必须等同于以下
extern "C" void fun(int sig);
[编辑] 返回值
成功时返回先前的信号处理程序,失败时返回 SIG_ERR(在某些实现上可能禁用设置信号处理程序)。
[编辑] 信号处理程序
对作为信号处理程序安装的用户定义函数施加以下限制。
如果信号处理程序被调用不是因为 std::abort 或 std::raise(异步信号),则在以下情况下行为是未定义的:
信号处理程序调用标准库中的任何函数,除了
std::abort
std::_Exit
std::quick_exit
std::signal,其第一个参数是当前正在处理的信号编号(异步处理程序可以重新注册自身,但不能注册其他信号)。
信号处理程序引用任何具有静态存储持续时间的对象,但不是 std::atomic 或 (自 C++11 起)volatile std::sig_atomic_t 的对象。
(C++17 前)
“*纯粹的无锁原子操作*”是调用
f 是函数 std::atomic_is_lock_free, f 是成员函数 is_lock_free (例如 std::atomic::is_lock_free()), f 是 std::atomic_flag 的非静态成员函数, f 是非成员函数,且 f 的第一个参数类型为 *cv* std::atomic_flag*, f 是在一个对象 obj 上调用的非静态成员函数,使得 obj.is_lock_free() 产生 true,或 f 是一个非成员函数,并且对于传递给 f 的每个原子指针参数 arg,std::atomic_is_lock_free(arg) 产生 true。
如果任何信号处理程序执行以下任何操作,则行为是未定义的
调用任何库函数,除了纯无锁原子操作和以下 *信号安全* 函数(请特别注意,动态分配不是信号安全的)
std::signal,其第一个参数是当前正在处理的信号编号(信号处理程序可以重新注册自身,但不能注册其他信号)。std::numeric_limits 的成员函数 std::_Exit
std::abort
std::quick_exit
std::initializer_list 的成员函数,以及 std::begin 和 std::end 的 std::initializer_list 重载 std::forward、std::move、std::move_if_noexcept来自
访问具有线程存储持续时间的对象一个 dynamic_cast 表达式一个 throw 表达式进入 try 块初始化执行动态非局部初始化的静态变量(包括延迟到首次 ODR-use)等待任何具有静态存储持续时间的变量的初始化完成,因为另一个线程正在同时初始化它
(C++17 起)
如果用户定义函数在处理 SIGFPE、SIGILL、SIGSEGV 或任何其他指定计算异常的实现定义信号时返回,则行为未定义。
如果信号处理程序是由于 std::abort 或 std::raise(同步信号)而被调用的,则如果信号处理程序调用 std::raise,则行为未定义。
进入信号处理程序时,浮点环境的状态和所有对象的值都是未指定的,除了
类型为 volatile std::sig_atomic_t 的对象
无锁 std::atomic 类型的对象通过 std::atomic_signal_fence 可见的副作用
(C++11 起)
从信号处理程序返回时,任何由信号处理程序修改的非 volatile std::sig_atomic_t 或无锁 std::atomic 对象的行为都是不确定的。
(直到 C++14)
调用函数 signal() 同步于任何由此导致的信号处理程序调用。
如果信号处理程序是由于调用 std::raise(同步)而执行的,则处理程序的执行 *序列在* std::raise 调用之后,*序列在* 其返回之前,并在与 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
#include
namespace
{
volatile std::sig_atomic_t gSignalStatus;
}
void signal_handler(int signal)
{
gSignalStatus = signal;
}
int main()
{
// Install a signal handler
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 是否是信号安全的
它是
[编辑] 参见
raise
为特定信号运行信号处理程序 (函数) [编辑]
atomic_signal_fence(C++11)
线程与在同一线程中执行的信号处理程序之间的屏障 (函数) [编辑]
C 文档 关于 signal
