32

2 つのスレッドがあり、1 つはループで bool を読み取り、もう 1 つは特定の時間にそれを切り替えることができるとします。sizeof(bool)個人的には、C++ では 1 バイトであり、バイトを部分的に読み書きしないため、これはアトミックである必要があると思いますが、100% 確実にしたいのです。

はいまたはいいえ?

編集

また、今後の参考のために、同じことが当てはまりますintか?

4

3 に答える 3

73

C++11 の「アトミック」型には、次の 3 つの個別の問題があります。

  1. ティアリング: 読み取りまたは書き込みには複数のバス サイクルが含まれ、操作の途中でスレッドの切り替えが発生します。これにより、誤った値が生成される可能性があります。

  2. キャッシュ コヒーレンス: 1 つのスレッドからの書き込みはそのプロセッサのキャッシュを更新しますが、グローバル メモリは更新しません。別のスレッドからの読み取りでは、グローバル メモリが読み取られ、他のプロセッサのキャッシュに更新された値が表示されません。

  3. コンパイラーの最適化: コンパイラーは、値が別のスレッドからアクセスされないという前提で読み取りと書き込みの順序をシャッフルするため、混乱が生じます。

を使用std::atomic<bool>すると、これら 3 つの問題すべてが正しく管理されます。使用しないstd::atomic<bool>と、せいぜい移植性のないコードで推測できます。

于 2013-01-31T11:53:10.210 に答える
19

それはすべて、「原子」という言葉が実際に何を意味するかによって異なります。

「最終値は一度に更新される」という意味ですか (はい、x86 では、バイト値が確実に保証されています - 少なくとも 64 ビットまでの正しく整列された値)、または「これを true に設定した場合 (またはfalse)、設定した後に他のスレッドが別の値を読み取ることはありません」(これはそれほど確実ではありません。それを保証するには、「ロック」プレフィックスが必要です)。

于 2013-01-31T11:46:07.837 に答える
6

x86 では、ワード サイズのワード アラインされた読み取りと書き込みのみが保証されます。明示的にアトミックでない限り、他の操作は保証されません。さらに、もちろん、最初に関連する読み取りと書き込みを実際に発行するようにコンパイラーを説得する必要があります。

于 2013-01-31T11:46:07.183 に答える