マルチコアと同期

上のコードは、CAS(&p, 期待値, 新しい値)を使って共有の変数counterを2倍にしている。CASが失敗してループをやり直すのはどのようなときか。

int old, new;
do {
    old = counter;
    new = old * 2;
} while (!CAS(&counter, old, new));
  1. Acounterの値が0のとき
  2. Boldを読んでからCASを実行するまでの間に、ほかのスレッドがcounterを書き換えたとき
  3. Cnewの値がoldより大きいとき
答えと解説を見る

正解:B. oldを読んでからCASを実行するまでの間に、ほかのスレッドがcounterを書き換えたとき

CASは、counterが読んだときのoldのままなら新しい値を書き込みます。その間にほかのスレッドが値を変えていると、手元のnewは古い値をもとに計算したものなので書き込まず、失敗を返します。ループは最新の値を読み直して計算をやり直します。足し算だけならフェッチ・アンド・アッドで済みますが、2倍にするような任意の更新もこの形で不可分に行えます。

  • A. 0でも、ほかから変えられていなければ成功します。
  • B. 正しい。古い値をもとにした計算を捨ててやり直します。
  • C. 値の大小は失敗の条件ではありません。
この分野を解く 分野ページへ

マルチコアと同期のほかの問題

  1. RISC-VのLR/SC(ロード予約/条件付きストア)のような命令の組で、SC(条件付きストア)が失敗するのはどのようなときか。
  2. CASを使ったロックフリーのデータ構造で問題になるABA問題の説明として正しいものはどれか。
  3. RISC-Vのamoadd.w命令やx86のlock xadd命令のような、フェッチ・アンド・アッド(fetch-and-add)命令の動作として正しいものはどれか。
  4. スピンロックの説明として正しいものはどれか。
  5. スピンロックが向かない場面として最も適切なものはどれか。