複数のスレッドが同じ値を同じ変数に同時に安全に書き込むことができますか?
特定の例として、以下のコードは、C ++標準によって、すべての準拠システムでコンパイル、未定義の動作なしで実行、「true」を出力することが保証されていますか?
#include <cstdio>
#include <thread>
int main()
{
bool x = false;
std::thread one{[&]{ x = true; }};
std::thread two{[&]{ x = true; }};
one.join();
two.join();
std::printf(x ? "true" : "false");
}
これは理論的な質問です。実際に機能するかどうかではなく、常に機能するかどうか(またはこのようなコードを書くのが良い考えかどうか:))を知りたいです。誰かが規格の関連部分を指摘していただければ幸いです。私の経験では、それは常に実際に機能しますが、それが機能することが保証されstd::atomic
ているかどうかわからないので、代わりに常に使用します-この特定のケースに厳密に必要かどうかを知りたいです。
番号。
ミューテックスを使用するか、アトミックにすることにより、これらの変数へのアクセスを同期する必要があります。
同じ値が書き込まれている場合の免除はありません。その値の記述にどのような手順が含まれるか(これは根本的な実際的な懸念事項です)、またコードが未定義の動作をする理由である標準もわかりません…つまり、コンパイラーはプログラムで絶対的な混乱を引き起こすことができます(あなたが避ける必要がある本当の問題)。
誰かがやって来て、そのようなアーキテクチャがこれらのサイズの変数へのアトミック書き込みを保証するとあなたに言うでしょう。しかし、それはUBの側面を変えるものではありません。
あなたが探しているパッセージは次のとおりです。
[intro.races/2]
:一方がメモリ位置([intro.memory])を変更し、もう一方が同じメモリ位置を読み取るか変更すると、2つの式の評価が競合します。
[intro.races/21]
:[…]プログラムの実行には、競合する可能性のある2つのアクションが含まれている場合、データ競合が含まれます[…]。このようなデータの競合は、未定義の動作を引き起こします。
…そして周囲の言葉遣い。このセクションは実際には非常に難解ですが、これはプログラミングに関するどの本でも読むことができる古典的な教科書のデータ競合であるため、実際に解析する必要はありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加