2つのスレッドがあるとします.1つはループ内のブールを読み取っており、もう1つは特定の時間にそれを切り替えることができます。個人的には、これはC++のsizeof(bool)
が1バイトであり、部分的に読み書きはしないので、これはアトミックでなければならないと思いますが、100%確実にしたいです。boolの読み取り/書き込み操作はx86上で不可分ではありませんか?
はい、いいえですか?
EDIT:今後の参考のためにも
、同じことがint
にも適用されますか?
2つのスレッドがあるとします.1つはループ内のブールを読み取っており、もう1つは特定の時間にそれを切り替えることができます。個人的には、これはC++のsizeof(bool)
が1バイトであり、部分的に読み書きはしないので、これはアトミックでなければならないと思いますが、100%確実にしたいです。boolの読み取り/書き込み操作はx86上で不可分ではありませんか?
はい、いいえですか?
EDIT:今後の参考のためにも
、同じことがint
にも適用されますか?
「原子」という言葉が実際に何を意味するかによって異なります。
「最終値は一度に更新されます」(確かに、x86では確実にバイト値が保証されていますが、64ビットまでは正しく整列されています) true(またはfalse)に設定すると、他のスレッドは設定した後に別の値を読み取ることはありません」(これはあまり確実ではありません。
のアーキテクチャで作業しました。 "これをtrue(またはfalse)に設定すると、他のスレッドは設定した後に別の値を読み込めません"。私は質問がかなり明確だと思う。この後者の解釈は、原子性とは関係がありません。 – jberryman
@jberryman:この問題には、キャッシュとメモリの読み込みを最適化するコンパイラがあります。あるスレッドでは、 'b = false;'は、他のスレッドが 'if(b)...'の次のケースで 'b'が偽であることを保証するものではありません。これは、コンパイラが 'b 'へのアクセスを' tmp = b; ... if(tmp)... '[[' tmp'はレジスタです]。スレッド内のコードに応じて、コンパイラがこれを行う状況があります。 –
x86では、ワードサイズのワード単位での読み取りと書き込みが保証されています。明示的に原子的でない限り、他の操作を保証するものではありません。もちろん、最初に関連する読み書きを実際に発行するようにコンパイラに納得させる必要があります。
3つの別々の問題があり、そのC++ 11個のアドレスで「アトミック」タイプ:
引き裂き:読み取りまたは書き込みが複数のバスサイクルを必要とする、及びスレッドスイッチが操作の途中で発生します;誤った値が生成される可能性があります。
キャッシュの一貫性:あるスレッドからの書き込みでプロセッサのキャッシュが更新されますが、グローバルメモリは更新されません。別のスレッドからの読み取りではグローバルメモリが読み込まれ、他のプロセッサのキャッシュでは更新された値は表示されません。
コンパイラの最適化:コンパイラは、値が別のスレッドからアクセスされず、混乱を招くという前提で、読み書きの順序をシャッフルします。
std::atomic<bool>
を使用すると、これら3つの問題すべてが正しく管理されます。 std::atomic<bool>
を使用しないと、移植性が高くないコードを推測することができます。
基礎となるアーキテクチャーのワードサイズよりも小さくても、アトム*とそれよりも効率的ではありませんか? –
http://stackoverflow.com/questions/8037289/is-mutex-required-for-1-byte-shared-memoryは非原子性であることを示しています。 –
http://stackoverflow.com/questions/8517969/is-this-the-correct-way-to-atomically-read-and-write-a-boolは、「ほとんどのマシンでは」原子的であることを示しています。 –