2

次のコードがあるとしましょう (おもちゃの例):

std::atomic<K *> data;
K *old_value = NULL;
K *new_value = new K();
if (!data.compare_exchange_strong(old_value, new_value, m1, m2)) {
    delete new_value;
}
do_something(old_value);

または

std::atomic<K *> data;
K *i = data.load(m3);
K *j;
do {
   j = i + 1;
} while (data.compare_exchange_weak(i, j, m4, m5);
do_something(j);

m1m2m3m4の有効な値はm5? std::memory_order_relaxed私の読書は、コード全体が以前の操作の結果に強く依存するため、すべてが可能であるということです(do_somethingポインターを使用するだけで、グローバルな共有状態を変更しないと仮定します)。私の読みは正しいですか?

4

1 に答える 1

4

この質問は、明確に定義された共有状態を持つマルチスレッド シナリオでのみ意味があります。他のスレッドが何をしているのかわからないので、それが読み取り/書き込みを行っているとしか思えませんdata。この単一の同期ポイントだけで、すべてリラックスした順序付けがうまくいくはずです。他の同期点から独立していると見なされる特定のアトミックについては、操作は依然としてアトミックであり、それらの相対的な順序は依然として正確です。

ここで、共有状態が複数の変数で構成されている場合 (ここで「順序付け」が機能します)、まったく別の話になります。取得/解放などについて心配する必要があります。セマンティクス。この場合:

relaxed

  • あるスレッドからのいくつかの変数への変更が、同じ順序で別のスレッドに表示されることを保証しません。
  • 異なるスレッドから独立して行われたいくつかの変数 (たとえば、スレッド 1 のセットdata1とスレッド 2 のセットdata2) への変更が、他のすべてのスレッドに同じ順序で表示されることは保証されません。

acquire/release(すべての読み取り/書き込みでそれぞれ使用すると、順序付け引数のパターンが異なるため、最初の項目がより緩和される場合があります)

  • あるスレッドからのいくつかの変数への変更が、同じ順序で別のスレッドに表示されることを保証します。
  • 異なるスレッドから独立して行われたいくつかの変数への変更が、同じ順序で他のすべてのスレッドに表示されることを保証するものではありません。

seq_cst(繰り返しますが、すべての読み取り/書き込みで使用する場合):

  • あるスレッドからのいくつかの変数への変更が、同じ順序で別のスレッドに表示されることを保証します。
  • 異なるスレッドから独立して行われたいくつかの変数への変更が、それが何であれ、同じ順序で他のすべてのスレッドに見えることを保証します。
于 2012-08-01T17:29:25.197 に答える