プロセス制御ブロック
プロセス制御ブロック(プロセスせいぎょブロック、Process Control Block、PCB)とは、オペレーティングシステムのカーネルにおいて対応するプロセスの状態を表すデータ構造。オペレーティングシステム (OS) によっては、保護された便利な配置としてプロセス毎のカーネルスタックの先頭部分にPCBが置かれる。
なお、OSによっては「プロセス」の代わりに「タスク」という用語を使う場合があり、その場合にはタスク制御ブロック (Task Control Block, TCB) と呼ばれるが、PCBと同じ物と考えてよい。
概要
実装は様々であるが、一般的にPCBは直接/間接に以下のような項目を保持する。
- プロセスを識別する番号(プロセス識別子、あるいはPID)
- そのプロセスのレジスタ群の値、特に
- そのプロセスのプログラムカウンタの値
- そのプロセスのアドレス空間(の管理データ)
- オープンしているファイルとソケットのリスト
- プロセス・アカウンティング情報:プロセスが最近動作した時刻、これまでに消費したCPU時間の合計など
コンテキストスイッチのとき、現在実行中のプロセスは一時停止し、他のプロセスが実行のチャンスを与えられる。カーネルは実行中のプロセスを停止し、そのときのレジスタの値をPCBにセーブし、新たに動作させるプロセスのPCBからレジスタに値をリストアする。
カレントPCB
カーネル内のコードは頻繁に現在走行中のプロセスのプロセス制御ブロック (PCB) にアクセスする。通常、グローバルなポインタ変数で現在のプロセスのPCB(カレントPCB)を指す。また、カーネル内のシステムコール処理はプロセス毎に行われるものであるため、カーネルスタックはプロセス毎に必要となる。これを簡単に管理するため、PCBとカーネルスタックを一体化させることがある。
グローバル変数を使うと間接アクセスになるため性能的に不利となる。そこで性能向上のためにカレントPCBを固定の仮想アドレスにマッピングすることがある。例えば、MIPSアーキテクチャでは 0番地の前後へのアクセスについてゼロレジスタ(内容が常にゼロ)をポインタのように扱って非常に効率的なコードを書くことができる。これを利用して仮想空間の最も大きなアドレス(32ビットならば 0xFFFFFFFF)付近にPCBとカーネルスタックをマッピングすることが多い(負のオフセットとゼロレジスタでPCBにアクセス可能)。
一般にカーネル内ではプロセス毎にスタックがあるため、そのサイズはユーザ空間のコールスタックほど大きくできない。そのため、カーネル内のコードはスタック上に大きな局所変数領域を持たないよう注意しなければならないし、再帰呼び出しも避けなければならない。
マルチプロセッシングでは、各プロセッサがそれぞれ異なるプロセスを実行するため、カレントPCBもプロセッサ毎に存在する。
ライトウェイトプロセス
ユーザープロセスのマルチスレッドをカーネルが認識して処理する場合(ライトウェイトプロセス)、各スレッドがカーネル内にコンテキストを持つ。従って、PCBはプロセス全体に関わる部分(アドレス空間関連やファイル関連)とコンテキストスイッチに関わる部分に分けられ、後者はスレッド(ライトウェイトプロセス)毎に作成される。これはある意味でプロセス管理のふたつの大きな機能(プロセス毎の資源割り当て管理とプロセスあるいはライトウェイトプロセスの状態管理)に対応している。