C 同時プログラミング: アトミック クラスとメモリ バリアを使用して同時実行の安全性を確保する
マルチスレッド環境では、同時プログラミングは共有処理を処理します。リソース 一般的なテクニック。ただし、適切な対策が講じられていない場合、同時アクセスによりデータ競合やメモリの可視性の問題が発生する可能性があります。これらの問題を解決するために、C はアトミック クラスとメモリ バリアを提供します。
アトミック クラス
アトミック クラスは、基本型をカプセル化する特別なクラスで、マルチスレッド環境であってもそのインスタンスへのアクセスがアトミックであることを保証します。これにより、共有変数の読み取りおよび書き込み時のデータ競合が回避されます。
メモリ バリア
メモリ バリアは、異なるスレッド間でプログラムを強制的に実行するために使用される特別な命令です。これらにより、バリアの前に実行されたすべてのメモリ アクセスがバリアの後にも表示されるようになります。 C では 4 種類のメモリ バリアが提供されています。
memory_order_acquire
: 順不同アクセスを禁止し、バリアの前のすべての書き込みがすべてのスレッドに確実に表示されるようにします。 memory_order_release
: アウトオブオーダーアクセスを無効にし、バリア後のすべての読み取りが以前のすべての書き込みを取得するようにします。 memory_order_acq_rel
: memory_order_acquire
と memory_order_release
の関数を組み合わせます。 memory_order_seq_cst
: すべてのプログラムの順序を保証するための最も厳格な障壁。 実際的なケース
2 つのスレッドがカウンターを共有する次の例を考えてみましょう。
// 原子计数器 std::atomic<int> counter; void thread1() { // ... counter.fetch_add(1, std::memory_order_release); // ... } void thread2() { // ... int value = counter.load(std::memory_order_acquire); // ... }
In thread1
、 fetch_add
オペレーションは memory_order_release
バリアを使用して、counter
への書き込みがすべてのスレッドで確実に認識されるようにします。 thread2
では、load
操作で memory_order_acquire
バリアを使用して、counter## を読み取る前に、前のすべての
counter## ペアが取得されるようにします。 # 書いています。これにより、データ競合やメモリの可視性の問題が解消されます。
注
メモリバリアによりパフォーマンスが低下する可能性があります。したがって、必要な場合にのみ使用してください。さらに、常にstd::memory_order_seq_cst を使用してください。これにより、最高のメモリ可視性が保証されますが、パフォーマンスのオーバーヘッドも最高になります。
以上がC++ 同時プログラミング: アトミック クラスとメモリ バリアの使用方法?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。