複数のスレッドが共有グローバル変数に同時にアクセスする場合、スレッドは次のコマンドを使用して変数に書き込み、または変数から読み取ることがあります。異なるコピーは異なるプロセッサ コアにキャッシュされます。異なるキャッシュに格納されている値の間に不一致がある可能性があるため、1 つのスレッドがそのキャッシュから古い値を読み取る可能性があります。
ただし、C 11 標準では、アトミック操作用の std::atomic ライブラリが提供されています。 、最新の値が他のキャッシュから確実に読み取られるようにします。これは、あるスレッドによって行われた変更が他のスレッドにも一貫した順序で表示されることを保証する、強力なメモリ順序付けによって実現されます。
一方、volatile キーワードは、単に変数が次の方法で最適化されるべきではないことを示します。ただし、アトミック アクセスは保証されません。これは、主にメモリマップされた I/O や信号処理などのシナリオ向けに設計されています。
次のようなスレッド間の共有変数のコンテキストでは、
std::atomic<int> ai;
の動作揮発性タイプとアトミックタイプは大きく異なります。 volatile はアトミック アクセスを保証するものではなく、std::atomic と組み合わせて使用するのは冗長です。ハードウェア プラットフォームが別の方法で指定している場合、volatile はアトミック アクセスやスレッド間のメモリの順序付けに関係がない可能性があります。
一方、std::atomic 型は、std::memory_order_seq_cst などのさまざまなオプションを通じてメモリの順序付けを提供します。これにより、すべての変数にわたるすべてのアトミック操作に対して単一の合計順序が強制されます。これにより、可視性と順序付けの制約が確実に維持され、スレッドは厳密に定義された順序で古い値を監視しなくなります。
さらに、exchange()、compare_exchange_strong()、fetch_add などの読み取り、変更、書き込み操作を使用します。 () は最新の値へのアクセスを保証します。同じスレッド コンテキスト内でこれらの操作を実行することにより、スレッドは更新された値を正しい順序で監視し、不一致を回避します。
アトミック操作を使用する場合は、慎重な検討と理解が必要です。実稼働コードにアトミックオペレーションを効果的に実装するには、背景資料と既存のコードを徹底的に調査することをお勧めします。多くの場合、アトミック操作の課題が必要ない場合、ロックは実行可能な代替手段となります。
以上が同時 C 11 プログラミングにおける「std::atomic」と「volatile」の違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。