プロセスグループ

プロセスグループ (Process Group) とは、POSIX準拠のオペレーティングシステムにおいて、1個以上のプロセスの集まりを意味する。この集まりはプロセスグループリーダーとなっているプロセスのプロセスIDと同じ値をプロセスグループIDとして識別に使用する。

プロセスグループはシグナルを複数のプロセスに配布するために使用される。killシステムコールはシグナルを個々のプロセスに送るだけでなく、プロセスグループに送ることもできる。プロセスグループに向けられたシグナルは、そのグループのメンバーである全プロセスに送られる。

プロセスグループへのシグナル送信は、シェルプログラムが使用するジョブコントロールの基本となっている。ttyデバイスドライバは、キーボードからの割り込みを契機としてフォアグラウンドのプロセスグループに SIGTSTP、SIGQUIT、SIGINTというシグナルを送る。また、フォアグラウンドでないプロセスグループが端末からの入力待ち状態（また、適切なフラグが設定されていれば表示待ち状態も）になっている場合にSIGTTINシグナルやSIGTTOUシグナルを送る。シェル（ひいてはその操作者）はコマンドパイプラインからプロセスグループを生成し、どのプロセスグループが端末の制御を握るフォアグラウンドのプロセスグループになるかを制御する。

プロセスグループは常にひとつのリーダーから始まるが、必ずしも常にリーダーが必要というわけではなく、リーダーが他のプロセスより先に終了しても構わない。ただし、プロセスグループのリーダーが制御端末を有するセッションのリーダーを兼ねている場合は別で、後述するようにセッションの各プロセスに影響を与える処理が実行される。POSIXの仕様では、プロセスが偶然にグループリーダーなることはないと定めている。そのため、あるプロセスIDがプロセスグループIDとして使われている間は、それがプロセスIDとして再利用されないようにする必要がある。プロセスグループのリーダーになるには、明示的に setpgid() または setsid() システムコールを呼び出す必要がある。

setpgid()システムコールは新たなプロセスグループを生成したり、プロセスを既存のプロセスグループに入れたりする汎用の呼び出しである。リーダーになるには、自身のプロセスIDを指定すればよいが、通常 setpgid(0,0) という形で呼び出す。シェルがコマンドパイプラインのために新たな子プロセスをforkすると、親であるシェルプロセスと子プロセスは直ちにそのプロセスをプロセスグループリーダーにしようとする。（両者がそれを試みるのは、子プロセスがプロセスグループリーダーになろうとすること、子プロセスがコマンドを実行しようとすること、親または端末デバイスドライバがジョブコントロールのシグナルをそのプロセスグループに送ろうとすること、これらの競合状態が発生するのを防ぐためである。）

プロセスグループ自体はセッション (session) の一員となる。これは制御端末がジョブ制御上重要な役割を担っていた、TSS上にて多数のユーザにテキストユーザインタフェースを提供するUnix系システムで使われたもので、いわゆる「ログインセッション」を意味している。セッションリーダーと呼ばれるひとつのプロセスが制御端末とやり取りし、端末が切断されるときにセッションのフォアグラウンドプロセスグループへシグナルSIGHUPを送信してそれらが停止することを保証する。また、制御端末とのI/Oを強制的に終了させ、次のログインセッションにてその端末を再利用できるようにする。セッションリーダーがいない場合、その端末のフォアグラウンドのプロセスグループがセッション内の他のプロセスグループの面倒も見ることが期待されている。プロセスは異なるセッションのプロセスグループに移動することはできず、プロセスグループも別のセッションに移動することはできない。プロセスグループを生成するプロセスは、自身が入っているセッション内でしかプロセスグループを生成できない。

ネットワーク経由でのログインや X Window System 等の グラフィカルユーザインタフェース (GUI) における xterm のような端末エミュレータが使われるようになって、TSS向けに実装されたジョブ制御の需要は少なくなり、カーネルがセッションに関して行っていた処理の大部分も無視されている。特に、端末エミュレータやネットワーク経由のログインでは接続が不意に切断されてしまった場合でもフォアグラウンドプロセスグループが実行を続けられるようにするため、シェルがプロセスを開始する際にSIGHUPを無視させるように設定することが一般的になっている。GUIではTSS由来のセッション管理は端末エミュレータにて実行したシェル上でのジョブ制御にとどめられ、GUIそのもののログインセッション管理に関しては全く別の機構を使用している。

setsid()システムコールを使用して新しいセッションを作る。成功すると、プロセスグループは複数のセッションにまたがることができないため、そのプロセスは同時に新たなプロセスグループリーダーにもなる。つまり、このシステムコールはひとつの新しいプロセスグループを持つ新しいセッションを生成することを目的としている。そのとき現在のプロセスがセッションとプロセスグループのリーダーとなる。注意点として、既存のプロセスおよびプロセスグループがセッションを移動することは仕様上許されていないため、プロセスグループのリーダーであるプロセスが setsid() を実行することはできず、エラーとなる。この制限により、デーモンプロセスの作成には fork() の実行が必須となる。

 脚注 

 外部リンク 
4.4BSD オペレーティングシステムの設計と実装

ふろせすくるうふ
ふろせすくるうふ