0.5 プロセス管理

 プロセス管理は、プログラムの実行状態を管理します。Linuxカーネルは、指定されたプログラムを実行するための環境を構築し、プログラム実行が終了するときれいに掃除します。

 Linuxカーネルはプロセスごとに、そのプロセスを管理するためのデータ構造を用意しています。おのおののデータ構造は、プロセスID、実行優先度、プロセス空間情報、利用中のファイルに関する情報などさまざまなものを管理します。

 プロセスIDはプロセスを識別するために利用されますが、プロセスID以外にプロセスグループID、セッションIDという識別子も与えられます。セッションIDは、同じ制御端末に結び付けられたプロセス群に対し与えます。一般に、1つのloginコマンドから派生したプロセス群が、同じセッションIDを持ちます。プロセスグループIDは、典型的にはジョブ、つまりパイプで接続されたプロセス群が同じIDを共有します。通常はシェルがこのプロセスグループIDを制御します。これらセッションとプロセスグループは、シグナル機構とも密接に関係しています。

 本書のPart 2で詳しく扱います。

0.5.1 プロセス

 Linuxのプロセスは、必ずforkシステムコールを発行したプロセス(親プロセスと呼びます)の子供(子プロセス)として生成されます(図0-4)。子プロセスはforkシステムコールによって、親プロセスのすべての属性を引き継いだそっくりのプロセスとして生まれます。複製する情報には、プロセス空間情報、ファイルのオープン状態、カレント作業ディレクトリ情報、シグナル動作設定などさまざまなものがあります。複製が完了すると、その複製を子プロセスとして、プロセススケジューリング対象に加えます。親子プロセス間で異なるものは、プロセスIDのみです(正確には一部例外あり)。

 以上の手続きの後、execシステムコールによって、目的のプログラムの実行を開始します。プロセスごとに用意されたデータ構造上にある情報のうち、プロセス空間に関する情報をいったんすべて破棄し、そのあとexecで指定されたプログラムを貼り付けたプロセス空間を生成します。それ以外の情報は、exec以前のものをそのまま利用するようになっています。プロセスID、利用中のファイル、カレント作業ディレクトリ情報などは、変化しません。

 Linuxカーネルのexec機構は、ダイナミックリンクライブラリの利用を許しています。ライブラリを目的のプログラムとは別オブジェクトのままファイルシステム上に置いておき、実行時に動的にプロセス空間に貼り付け、リンク処理を行います。

 exitシステムコールは、プロセスを終了させるシステムコールです。つまり、プロセスに関係する情報や資源をすべて破棄するシステムコールです。プロセス仮想空間とその空間に割り当てられていた実メモリを解放し、利用中(オープン中)であったファイルも自動的にクローズします。

 また、親プロセスはwaitシステムコールを用いて、子プロセスの終了を待ち合わせることができます。親プロセスは子プロセスの終了状態(正常終了、異常終了、シグナル受信)などを得ることが可能です。この仕組みを実現するため、Linuxカーネルはexitシステムコールを発行した子プロセスの管理データの解放を、waitシステムコールが発行されるまで一部保留するようになっています。この保留状態は、ZOMBIEプロセスとしてpsコマンドで確認できます。

 「第7章 プロセス管理」では、プロセスの一生の動きを説明します。

0.5.2 シグナル

 シグナルは、プロセスに非同期事象を伝えるための簡単な仕掛けです。シグナルは、Linuxカーネル内のさまざまな個所で発生します。シグナルを受けたプロセスは、その設定によりデフォルト動作、無視、シグナルハンドラ実行を選択できます。デフォルト動作はシグナル種別に依存しており、単にプロセスを終了させるシグナルがほとんどですが、コアダンプさせるシグナルや、プロセス実行を中断させるシグナルなどもあります。

 現代のシグナルの動作は、旧来のUNIXにBSDが独自にさまざまな拡張を加えたものとなっています。大きな機能強化には、シグナルマスク機能、プロセス実行中断シグナル、シグナルスタックなどがあります。また、それ以外の細かい動作も変更が加えられています。Linuxカーネルの実装は、可能な限りこれらの新しいシグナル動作もエミュレートしています。

 シグナルハンドラを実行するプロセスの動作は、割り込みを受け付けたときのLinuxカーネルの動作によく似ています。Linuxカーネルは、シグナルを受けたプロセスの実行をいったん中断します。そのあとシグナルハンドラを実行し、シグナルハンドラが終了すると、先ほどの中断地点からプロセスの実行を再開させます。

 「第8章 シグナル」において、シグナル機構を実現するための仕組みを説明します。

0.5.3 スレッド

 Linuxカーネルのスレッドは、一種のプロセスとして実装されています。プロセスと異なる点は、スレッド間でプロセス空間を共有している点と、スレッドどうしで関係情報を保持している点です。Linuxカーネルの実装では、プロセス管理のデータ構造をそのまま利用することによって、スレッド管理を実現しています。プロセススケジューラから見た場合、両者はまったく同じ存在です。

 プログラマが利用するPOSIXスレッドインターフェイスは、Linuxカーネルが提供する生のインターフェイスではなく、ライブラリによって実現しています。ライブラリが、POSIXスレッドインターフェイスをLinuxカーネルのスレッドインターフェイスに変換します。

 スレッドに関する話題も「第7章 プロセス管理」にて、詳しく説明します。