关于信号安全的手册页给出了一长串可以从信号处理程序调用的函数,但没有提供明确的规则如何确定特定函数是信号安全的。
现在我对
jthread::request_stop
感兴趣,因为我想在 SIGINT 上优雅地终止我的线程。但我想知道是否有一些“经验法则”来确定某些特定函数是否可以被调用。
简短的回答是否定的。第 17.13.4 节信号处理程序
[support.signal]
指出:
评估是信号安全的,除非它包括以下内容之一:
—(3.1) 对任何标准库函数的调用,除了普通的无锁原子操作和明确标识为信号安全的函数; [注意:这隐式排除了依赖库提供的内存分配器的 new 和 delete 表达式的使用。 — 尾注]
在标记为信号安全的功能中,我找不到
request_stop
,因此不安全。
但是您不需要在信号处理程序中使用它。您只需检查两个可能停止的条件即可。像这样的东西:
#include <csignal>
// using std::sig_atomic_t, std::signal
#include <thread>
#include <iostream>
volatile std::sig_atomic_t term_requested;
int main()
{
std::signal(SIGINT, +[](int sig) {
term_requested = 1;
});
std::jthread thread{[](std::stop_token token) {
while(! term_requested || token.stop_requested()) {
}
std::cout << "Terminating thread\n";
}};
thread.join();
}