bool compare_exchange_weak (T& expected, T val, memory_order sync = memory_order_seq_cst) noexcept;
compare_exchange_weakの動作仕様がいつまでも覚えられないので、メモ。
覚える必要があるのは第一引数と第二引数と戻り値。
メモリオーダーはとりあえず無視して良い。
以下2つの動作仕様を覚えよう。
(A1) std::atomicインスタンスの値が、expectedの場合、インスタンスの値をvalの値に変更する。
この時の戻り値はtrue。
(A2) インスタンスの値がexpectedでない場合、expectedの値をインスタンスの値に変更する。
この時の戻り値はfalse。
以下のような使い方となる。
atomic<int> val = 0; int expected = val.load(); // C1 do { int next = expected + 1; // C2 } while( !val.compare_exchange_weak(expected, next) );
例えば、C1からC2までの間に別スレッドにより、valの値が100に変化したとする。
すると、条件式が成り立たず、(A2)が実行され、valの最新の値である100がexpectedに入るので、
expectedが100になり、戻り値はfalseになる。
ここで、再度nextの値が計算され直されて101になり次の比較では、条件式が成立し、(A1)が実行され、valに102が設定され、戻り値がtrueなので、whileループから抜ける。
これがatomicに値の変更を行うための基本的な仕組みである。
なお、nextの値がexpectedの値に依存しない場合はdo文は不要で、while分だけあれば良い。
- 作者: Anthony Williams
- 出版社/メーカー: Manning Publications
- 発売日: 2019/02/10
- メディア: ペーパーバック
- この商品を含むブログを見る