C++
编译器支持
独立和宿主式
语言
标准库
标准库头文件
具名要求
特性测试宏 (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( int sig, /* 信号处理程序 */* handler );
(1)
extern "C" using /* 信号处理程序 */ = 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
定义信号类型 (宏常量) [编辑]
handler
-
信号处理程序。这必须是以下之一 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 使用)等待任何具有静态存储持续时间的变量的初始化完成,因为另一个线程同时初始化它
(自 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++ 标准。
DR
应用于
已发布行为
正确行为
LWG 3756
C++17
不清楚 std::atomic_flag 是否是信号安全的
它是信号安全的
[编辑] 参见
raise
为特定信号运行信号处理程序 (函数) [编辑]
atomic_signal_fence(C++11)
线程和在同一线程中执行的信号处理程序之间的栅栏 (函数) [编辑]
C 文档 关于 signal