#include <unistd.h>
#include <csignal>
#include <exception>
#include <functional>
#include <iostream>
std::function<void(int)> g_signalHandler;
void signalWrapper(const int a) { g_signalHandler(a); }
int main() {
bool abort = false;
g_signalHandler = [&abort](const int) {
std::cout << "Abort" << std::endl;
abort = true;
};
struct ::sigaction signalAction = {};
signalAction.sa_handler = signalWrapper;
if (
::sigaction(SIGHUP, &signalAction, nullptr) != 0 ||
::sigaction(SIGINT, &signalAction, nullptr) != 0 ||
::sigaction(SIGTERM, &signalAction, nullptr) != 0
)
throw std::exception();
// Is it guaranteed that the new value of abort will be seen here without
// the need of std::atomic<bool> or volatile bool?
while (!abort)
::sleep(1);
return 0;
}
假设单线程程序、C++17 和 Linux
据我所知,使用普通的
bool
对于 while (!abort)
来说就足够了,而 std::atomic<bool>
/ volatile bool
则没有必要。我想确认这始终是正确的,并且我不必担心编译器优化读取值
据我所知,使用普通 bool 足以满足 while (!abort) 的要求,而 std::atomic / volatile bool 则没有必要。我想确认这始终是正确的,并且我不必担心编译器优化读取值
不,这是错误的,会导致数据竞争,这始终是未定义的行为。
您保证能够通过信号处理程序中定义的行为访问的唯一非局部变量是
volatile std::atomic_sig_t
类型的对象(通过volatile
泛左值访问);仅当信号处理程序和运行信号处理程序的线程之间独占共享(没有其他同步)时,没有其他线程std::atomic_flag
保证无锁;哪些 std::atomic
专业是无锁的,取决于平台,可以通过 is_lock_free
和 is_always_lock_free
成员进行检查。