事象の待ち合わせ――プロセススケジューリング(その5)UNIX USER 2004年6月号「Linuxカーネル2.6解読室」より転載(1/2 ページ)

Linuxカーネル上で動作するプロセスの状態は、大きく分けて2つある。1つは実行可能状態で、もう1つは待機状態(休止状態)だ。ここでは待機状態のプロセスについて詳しく解説していく。

» 2004年06月12日 00時00分 公開
[高橋浩和(VA Linux Systems Japan),UNIX USER]

 Linuxカーネル上で動作するプロセスの状態は、大きく分けて2つあります。1つは実行可能状態で、もう1つは待機状態(休止状態)です。実行可能状態のプロセスはスケジューリングの対象となり、プロセススケジューラは順番に実行権を与えていきます。待機状態のプロセスは、何らかの事象を待ち合わせている状態であり、ある条件が整うまでそれ以上の処理を継続できません。このようなプロセスは、スケジューリングの対象にはなりません。たとえば、ファイルのread処理を行っているプロセスは、ディスクへの入出力要求後、その入出力が完了するまで動作できません(図11)。実際、Linuxカーネル上で動作しているプロセスの大部分は、この待機状態にあります。

図11 図11 入出力の待ち合わせ(クリックで拡大します)

 待機状態のプロセスには2種類あります。1つはシグナルを受け付ける待機状態で、もう1つはシグナルを受け付けない待機状態です。前者はソケットや端末などでの事象発生を待ち合わせるときに利用します。目的の事象が発生するか、またはシグナルを受け取ると、待機状態は解除され、実行待ち状態に遷移します。後者はシグナルを受けても、シグナルを保留状態にしたまま待機状態を続けます

 Linuxカーネルはこれらの状態を区別できるように、task_struct構造体のstateメンバーに表1の状態を表す値を設定します。プロセスの状態遷移は図12のようになります。

表1 プロセスの状態
意味
TASK_RUNNING 実行可能状態(実行状態、実行待ち状態)
TASK_INTERRUPTIBLE 待機状態。シグナルによる待機状態解除可能
TASK_UNINTERRUPTIBLE 待機状態。シグナルによる待機状態解除不可

図12 図12 プロセス状態遷移(クリックで拡大します)

待機処理

 待機の対象となる可能性のあるカーネルオブジェクト(ファイルや、実ページ、端末など)は、それぞれWAITキュー(wait_queue_head_t型のリストヘッド)を用意しています。待機状態に遷移したプロセスは、ある事象の待ち合わせ用に用意されているWAITキューに登録されます。Linuxカーネル内には、さまざまなWAITキューが存在します。たとえば、ある端末の入力待ちのWAITキュー、ページキャッシュ上のページへの入出力完了を待ち合わせるためのWAITキュー、子プロセスの終了を待ち合わせるためのWAITキューなどがあります。

 待機状態のプロセスは、図13のような形式でWAITキューに登録されます。WAITキューに直接task_struct構造体を登録することはせずに、wait_queue_t型のデータ構造を介して間接的に登録します。

図13 図13 WAITキュー(クリックで拡大します)

 実行中プロセスを待機状態に遷移させる関数は、実行中プロセスを待機状態にするsleep_on( )関数(リスト5)と、実行中プロセスをシグナル受信可能な待機状態にするinterruptible_sleep_on( )です。これらの関数は、プロセス状態をそれぞれTASK_UNINTERRUPTIBLE、TASK_INTERRUPTIBLEに変更し(52)、スタック上に確保したwait構造体(51)を使って、目的の事象を待ち合わせるためのWAITキューに登録します(53)。その後、プロセススケジューラを呼び出し、実行権を放棄します(54)。

リスト5 sleep_on
void sleep_on(wait_queue_head_t *q)
{
    unsigned long flags;
    wait_queue_t wait;
    init_waitqueue_entry(&wait, current); ← 51
    current->state = TASK_UNINTERRUPTIBLE; ← 52
    spin_lock_irqsave(&q->lock,flags);
    __add_wait_queue(q, &wait); ← 53
    spin_unlock(&q->lock);
    schedule(); ← 54
    spin_lock_irq(&q->lock);
    __remove_wait_queue(q, &wait); ← 55
    spin_unlock_irqrestore(&q->lock, flags);
}

このページで出てきた専門用語
待機状態を続けます
シグナルについては、別の回に詳しく説明する。

       1|2 次のページへ

Copyright(c)2010 SOFTBANK Creative Inc. All rights reserved.

注目のテーマ