2 つの質問があります。1 つは共有データを変更し、もう 1 つは共有データを操作する 2 つのスレッドについて考えてみましょう。どちらのスレッドも、データを処理する前にミューテックスを取得します。
データを操作するスレッドが、最初のスレッドによって行われた変更を常に確認できるようにするにはどうすればよいですか? 一連の取得/解放フェンスが必要ですか、それともミューテックスを使用してスレッドを暗黙的に同期しますか? ミューテックスを使用しない場合 (ただし、排他的アクセスを保証する場合) はどうなりますか?
そして:フェンスは、インターリーブ/フォローアップのアトミック操作なしで実際に何かをしますか(atomic_boolにフラグを格納する、「準備完了」などを通知するなど)?
ユースケースは次のとおりです。
void func()
{
std::atomic_bool quit = false;
std::vector<float> data(100);
std::mutex m;
std::thread one([&]()
{
while (!quit.load(std::memory_order_relaxed))
{
std::unique_lock<std::mutex> lock(m, std::try_to_lock);
if (lock.owns_lock())
{
for (int i = 0; i < data.size(); ++i)
{
data[i] = std::rand();
}
std::atomic_thread_fence(std::memory_order::memory_order_release);
}
}
}
);
std::thread two([&]()
{
while (!quit.load(std::memory_order_relaxed))
{
std::unique_lock<std::mutex> lock(m, std::try_to_lock);
if (lock.owns_lock())
{
// guaranteed that any changes from thread one to 'data' is seen after this fence?
std::atomic_thread_fence(std::memory_order::memory_order_acquire);
auto res = std::accumulate(data.begin(), data.end(), 0);
std::cout << "Accumulated result is: " << res << std::endl;
}
}
}
);
fgetc(stdin);
quit.store(true);
one.join(); two.join();
}