これまで
シェルもどき「oreshell」を自作している。
前回は、oreshellにジョブ制御を実装しようとしたが、ジョブ制御を実現する前にプロセスグループを理解しておいたほうが良いらしいので、プロセスグループ/セッションについて調査した。
今回はoreshellの実装をプロセスグループに対応する。
また、oreshellをジョブ制御に対応するために、まずはジョブについて調べる。
こちらを参照。
要所だけ解説。
コマンドのパイプラインを実行するとき、コマンドが先頭であればプロセスグループリーダーになることを宣言し、先頭以外のコマンドは自身のプロセスグループIDのプロセスグループリーダーのプロセスIDを設定するように修正した。
前回説明した通り、プロセスグループとは
同じプロセスグループ ID を共有するプロセスの集まりである。 シェルは、一つのコマンドもしくはパイプラインの実行に使われるプロセス群に 対して一つのプロセスグループを生成する
である。それを確認する。
oreshellを起動し、
を実行。
もう一つ端末を開いてそこから
を実行。
「grep」プロセスのPIDが22087、PGIDが22087となっており、プロセスグループリーダーになったことがわかる。
「sort」プロセスのPGIDが22087となっており、grepのプロセスグループに属していることがわかる。
以上の通り、oreshellのプロセスグループ対応は完了。
で、次。ジョブとはなにか。
ジョブとは「人間がコンピュータに与える仕事の実行単位のこと」である。(参考)
人間が、「こういう処理をしたい」「ああいう処理をしたい」という要望をコンピュータに対して入力するときに、入力した要望のひとかたまりがジョブとなる。
Unix(とその眷属)の場合、シェルのプロンプトから入力したコマンド行1行がジョブである。
ジョブは1つ以上のプロセスで構成する。
先の例の場合
や
はそれぞれ1つのジョブである。
1つ目のジョブは1つのプロセスで構成し、2つ目のジョブは2つのプロセスで構成している。
前述したとおり、1つのコマンドもしくはパイプラインの実行に使われるプロセス群はプロセスグループである。
つまり、1つのコマンドもしくはパイプラインの実行に使われるプロセス群を、OSカーネルは「プロセスグループ」として管理し、シェルは「ジョブ」として管理する。
例としてシェル(bash)から以下を実行する。
この時のシェルとOSカーネルから見た、1つのコマンドもしくはパイプラインの実行に使われるプロセス群の扱いを図で示す。
OSから見ると、シェルもプロセスグループの1つである。
端末と結びついた複数のプロセスグループのうち、端末の入力を受け付けるプロセスグループは1つだけ。それをフォアグラウンドプロセスグループと呼ぶ。フォアグラウンドプロセスグループがシェルから起動したジョブの場合はフォアグラウンドジョブとも呼ぶ。
フォアグラウンドプロセスグループ/ジョブをシェルから起動する場合は、コマンド行の末尾に「&」をつけない。
それ以外の(端末の入力と切り離された)プロセスグループをバックグラウンドプロセスグループと呼ぶ。バックグラウンドプロセスグループがシェルから起動したジョブの場合はバックグラウンドジョブとも呼ぶ。
バックグラウンドプロセスグループ/ジョブをシェルから起動する場合は、コマンド行の末尾に「&」をつける。
例としてシェル(bash)から以下を実行したときの端末とフォアグラウンド/バックグラウンドのジョブ/プロセスグループの関係を図で示す。
まだシェルからジョブを起動していない。端末から入力を受け取るプロセスグループはシェル(bash)だけ。よって、フォアグラウンドプロセスグループはシェル(bash)。
この時点のジョブの数は0。
シェルからコマンド行
を実行する。末尾に「&」がついていることに注意。コマンド行はバックグラウンドプロセスグループ/ジョブとなる。
端末からの入力は引き続きシェル(bash)が受け取る。
この時点のジョブの数は1つ。
シェルから「cat」コマンドを実行する。
引数無しで「cat」コマンドを実行すると入力待ちになる。続けて入力した文字をおうむ返しで出力する。
コマンドの末尾に「&」がないため、「cat」コマンドがフォアグラウンドプロセス/ジョブとなる。端末からの入力は「cat」コマンドが受け取る。
シェル(bash)は「cat」コマンドを起動した後、バックグラウンドプロセスグループに切り替わる。「cat」コマンドが終了するかバックグラウンドに変更するまでこの端末からシェルに入力することはできない。
この時点のジョブの数は2つ。
Ctrl+dを入力すると「cat」コマンドは入力受付を終了して実行を終了する。
「cat」コマンドが実行を終了すると、シェル(bash)は再びフォアグラウンドプロセスグループに切り替わる。
この時点のジョブの数は1つ。
しばらく待っていると、「grep」「sort」のバックグラウンドプロセググループ/ジョブの実行が終了し、シェルが
を表示する。(bashの場合、自動通知するか、次のプロンプト表示で通知するかは「set -bまたは+b」)
ジョブの数は0。
ジョブの説明が終わったので次はジョブ制御とシグナルの話をする予定(たぶん)。