セマフォ

Linuxでは資源待ち合わせのための汎用関数として カウントセマフォが用意されている。待ち合わせが必要な資源内に semaphore型メンバを定義し,このメンバに対し、down関数 up関数を用いて資源獲得と解放を行うことができる。down関数で資源獲得に失敗した場合、up関数による資源解放が行われるまで、WAIT状態に移行する。

v2.2までは、up側では複雑な処理を行わず全てのプロセスを起こしてしまい、起き上がったプロセスどうしが早いもの勝ちでセマフォを取り(down)に行くようなコードになっていたが、v2.4からは先頭のプロセス一つのみに起床をかけるようなコードに変更されている。

以下にdown関数とup関数の大まかな流れを示す。(実際にはSMP対応で面倒なアセンブラコードも入っている)

Linuxの機能としては、シグナルで起床が可能なセマフォ関数(down_interrutptible)や、要求時点で獲得可能ならセマフォを確保するセマフォ関数(down_trylock)も用意されている。

img8.gif
  down(セマフォ)
        if (セマフォ値が残っていれば)
                セマフォ値を一つ減らし、return OK;

        スタック上にwait_queueを用意
        カレントプロセスの状態をTASK_UNINTERRUPTIBLE|TASK_EXCLUSIVEに変更
        wait_queueにカレントタスクを登録
        セマフォにwait_queueをリンク(add_wait_queue_exclusive関数)
        while(1) {
             if(セマフォ値が0である) {
                  スケジューラを呼び出してCPUを放棄する(schedule関数)
                  カレントプロセス状態をTASK_UNINTERRUPTIBLE|TASK_EXCLUSIVE
             } else {
                  セマフォ値を一つ減らす
                  カレントプロセス状態をTASK_RUNNINGに変更
                  セマフォからwait_queueを外す(remove_wait_queue関数)
                  return
             }
        }

  up(セマフォ)
        セマフォ値を一つ増やす
        このセマフォで待っているプロセスのうち先頭のものを
	    起こす(wake_up関数)

補足説明

XXX:性能面、効率面からは十分であるが、プロセス優先度という面からは問題が残る。本来、このセマフォで待っているプロセスのうち最もプライオリティの高いプロセスを起床すべきである。


(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST
1