cppreference.com将这个功能记录为“线程和在同一线程中执行的信号处理程序之间的围栏”。但我在互联网上找不到任何示例。
我不知道以下伪代码是否正确地说明了std::atomic_signal_fence()
的功能:
int n = 0;
SignalObject s;
void thread_1()
{
s.wait();
std::atomic_signal_fence(std::memory_order_acquire);
assert(1 == n); // never fires ???
}
void thread_2()
{
n = 1;
s.signal();
}
int main()
{
std::thread t1(thread_1);
std::thread t2(thread_2);
t1.join(); t2.join();
}
[否,您的代码未显示atomic_signal_fence
的正确用法。当您引用cppreference.com时,atomic_signal_fence
仅在信号处理程序和在同一线程上运行的其他代码之间执行同步。这意味着它不在两个不同线程之间执行同步。您的示例代码显示了两个不同的线程。
C ++规范包含有关此功能的以下注释:
[注:与
atomic_thread_fence
相同,禁止编译器优化和装入与存储的重新排序,但不会发出atomic_thread_fence本应插入的硬件防护指令。注意:
atomic_signal_fence
可用于指定线程执行的操作对信号处理程序可见的顺序。
这是正确的用法,如果没有动机的话:
static_assert(2 == ATOMIC_INT_LOCK_FREE, "this implementation does not guarantee that std::atomic<int> is always lock free.");
std::atomic<int> a = 0;
std::atomic<int> b = 0;
extern "C" void handler(int) {
if (1 == a.load(std::memory_order_relaxed)) {
std::atomic_signal_fence(std::memory_order_acquire);
assert(1 == b.load(std::memory_order_relaxed));
}
std::exit(0);
}
int main() {
std::signal(SIGTERM, &handler);
b.store(1, std::memory_order_relaxed);
std::atomic_signal_fence(std::memory_order_release);
a.store(1, std::memory_order_relaxed);
}
断言,如果遇到,则保证为真。
在您的示例中,您想使用std::atomic_thread_fence
(它将生成用于执行线程同步的机器代码);不是std::atomic_signal_fence
(仅禁用对原子变量的编译器内存重新排序优化)。就像其他人所说的那样,std::atomic_signal_fence
仅用于与原子操作在同一线程上的信号(我相信Windows上的结构化/矢量异常处理程序也同样适用,但请不要在此引用我的意思。) >