いいえ、あなたのコードは の正しい使い方を示していませんatomic_signal_fence
。cppreference.com を引用atomic_signal_fence
すると、シグナル ハンドラーと同じスレッドで実行されている他のコードの間でのみ同期を実行します。つまり、2 つの異なるスレッド間の同期は実行されません。あなたのコード例は、2 つの異なるスレッドを示しています。
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);
}
アサーションは、遭遇した場合、真であることが保証されています。