以下のコードは、atomic フラグを介して共有状態を取得する 2 つの方法を示しています。リーダー スレッドは or を呼び出しpoll1()
てpoll2()
、ライターがフラグを通知したかどうかを確認します。
投票方法 #1:
bool poll1() {
return (flag.load(std::memory_order_acquire) == 1);
}
投票オプション #2:
bool poll2() {
int snapshot = flag.load(std::memory_order_relaxed);
if (snapshot == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
return true;
}
return false;
}
オプション #1 は以前の質問で提示され、オプション #2 はcppreference.com のサンプル コードに似ていることに注意してください。
poll
関数が を返す場合にのみ共有状態を調べることに読者が同意すると仮定するとtrue
、2 つのpoll
関数はどちらも正しく同等でしょうか?
オプション #2 には標準名がありますか?
各オプションの利点と欠点は何ですか?
オプション #2 は、実際にはより効率的である可能性がありますか? 効率が悪い可能性はありますか?
完全な動作例を次に示します。
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
int x; // regular variable, could be a complex data structure
std::atomic<int> flag { 0 };
void writer_thread() {
x = 42;
// release value x to reader thread
flag.store(1, std::memory_order_release);
}
bool poll1() {
return (flag.load(std::memory_order_acquire) == 1);
}
bool poll2() {
int snapshot = flag.load(std::memory_order_relaxed);
if (snapshot == 1) {
std::atomic_thread_fence(std::memory_order_acquire);
return true;
}
return false;
}
int main() {
x = 0;
std::thread t(writer_thread);
// "reader thread" ...
// sleep-wait is just for the test.
// production code calls poll() at specific points
while (!poll2()) // poll1() or poll2() here
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::cout << x << std::endl;
t.join();
}