2.3.3 ビジーウェイトを用いた相互排他
相互排他を行う方法として、以下の5つがある。
- 割り込み(ハード)
- 割り込みを不許可にしてシステムクロックを止め、スケジューラが呼ばれないようにする。
少しでも間違えると、システムダウンを引き起こす。
- ロック変数(ソフト)
- ロック用に変数を用意したところで、タイミングによっては相互排他が行えないため、意味がない。
- 完全な交互実行(スピンロック)
- LinuxではCPU間の排他制御を行うために、スピンロックが使用される。
待ち時間が短いのが特徴だが、時間がかかるような処理にはCPUが常にフルで動作してしまうので用いてはいけない。
- Peterson
- ロック変数と完全な交互実行を組み合わせたもの。
- TSL(Test and Set Lock)命令
- 1回の命令で、比較と値のセットを行う。(atomic)
regをレジスタ、LOCKを適当なメモリのアドレスとした場合、ロックとアンロックのアセンブラによるコードは以下の通り。
ロック
lock:
tsl reg, [LOCK] # regにLOCKの値を代入し、LOCKに1を代入。アトミックな処理。
cmp reg, 0 # regと0を比較。
jne lock # regが0でなかったら、lockへ飛ぶ。(ロックを取得するまでループする。)
ret # ここまで来れたということは、ロックを取得できたということ。
アンロック
unlock:
mov [LOCK], 0 # LOCKに0を代入し、ロックを解放する
ret
優先度が低いプロセスがビジーウェイトのために、優先度が高いプロセスよりもCPUパワーを消費してしまう「優先度逆転問題」が生じてしまうことがある。
最終更新:2013年03月03日 23:09