プロセス管理 1 プロセスとは

プロセスとは

 Linuxでは実行中のプログラム ( アプリケーション ) を管理する単位をプロセスと言う。コマンドインタープリターであるシェル自身もプロセスである。

 ユーザがシェルからコマンドを実行すると、シェルは子プロセスとして自分の分身を作る。( これを fork と言う ) 次にシェルは子プロセスにコマンドの実行 ( これを exec と言う ) を任せ、子プロセスの終了を待つ。子プロセスはコマンドの実行を終えると親プロセスに終了を伝え、消滅する。親プロセスは子プロセスの終了を受け取り、シェルプロンプトを表示し、ユーザの次のコマンドに備える。

スケジューリング

 Linux は1つの CPU でも複数のユーザが同時にログインでき、複数のプロセスを同時に実行できるマルチユーザ、マルチタスクのOSである。しかし、厳密には瞬間瞬間ではプロセスは1つしか実行されず、それぞれのプロセスの実行順序は Linux のスケジューラによって管理されている。

 各プロセスは Run Queue と呼ばれる待ち行列で待機し、自分が CPU を利用できる順番を待つ。自分の順番が来ると CPU を使うことができ、一定時間 ( タイムスライス ) だけ処理を前に進める。一定の時間が超過すると、またキューで次の CPU 使用機会を待つことになる。このようなスケジューリングをラウンドロビン方式と呼ぶが、そのほかに FIFO方式 ( First In First Out ) もある。

 各プロセスはキューで待機するが、プロセスによっては優先度は高いものの、それほど高くないものもある。そのパラメータの1つに Nice値がある。 Nice値は、-20から19までの値を取り、-20が最も実行優先度が高く、19が最も低くなっている。nice コマンドにより実行優先度をプロセスに指定したり、実行中のプロセスについては、renice コマンドにより優先度を変更することができる。

フォアグランドジョブとバックグランドジョブ

 プロセスとよく似た管理単位としてはジョブがある。Linux が実行中のプログラムを管理する単位であるプロセスに対して、ジョブはシェルが管理するプログラムの単位である。シェルからコマンドを実行する場合、ジブをフォアグランドジョブとバックグランドジョブに切り替える機能がある。

 例えば、処理に時間のかかるジョブを実行した時に、何もせずジョブの完了を待つのではなく、その間に別の作業をしたり、進捗を確認したい場合がある。そんな時にジョブをバックグラウンドで実行すれば、同じ端末から別のコマンドを実行することができる。

 他にも、プログラムの編集作業を中断して、プログラムを試行し、また編集作業に戻る場合などに有効である。なぜなら、編集を中断した場合、編集の undo や redo が中断後でも継続できるからである。

 コマンドをバックグランドで起動するには、コマンドの後ろに & ( アンパササンド ) を付けて実行する。

$ my_heavy_script &

 実行中のコマンドをバックグランドに切り替えるには、^Z ( CTRL + Z ) でサスペンドしてから bg コマンドでバックグランドで実行を継続させる。 fg コマンドでフォアグランドに戻すこともできる。ジョブの状態は jobs コマンドで確認することができる。

$ my_heavy_script
^Z
[1]+ Stopped my_heavy_script

$ jobs
[1]+ Stopped my_heavy_script

$ bg
[1]+ my_heavy_script &

& jobs
[1]+ Runnning my_heavy_script

実行例 複数のジョブを実行して切り替えを試してみる。

$ sleep 3600& 
( 1時間スリープするプロセス )

$ sleep 3601&
$ sleep 3602&

$ jobs
[1]    running    sleep 3600
[2]  - running    sleep 3601
[3]  + running    sleep 3602  

$ %1
( [1]のジョブをフォアグランドジョブにする )
[1]    running    sleep 3600
^Z
( CTRL + Z でフォアグランドジョブをサスペンドする )
zsh: suspended  sleep 3600

$ % jobs
[1]  + suspended  sleep 3600
[2]    running    sleep 3601
[3]  - running    sleep 3602

$ %-
( - のついたジョブをフォアグランドジョブにする )
[3]  - running    sleep 3602
^C
( フォグランドにあるジョブを停止する )

$ %%
( + のついたジョブをフォグランドジョブにする )
[1]    continued  sleep 3600
^C
( フォグランドにあるジョブを停止する )

$ fg
( この場合の fg は %+,%-,%% と同じ動作になる )
[2]  + running    sleep 3601
^C
( フォグランドにあるジョブを停止する )

$ jobs
$ ( 実行中のプロセスは無いので何も表示されない )

プロセスID

 Linux のプロセスには一意の ID であるプロセスID ( PID ) フが付与される。自身の PID は $$ で取得できる。

$ echo $$
15081

オプション

ps [ オプション ]
現在実行されているプロセスのスナップショットを表示する

オプション

-A
全てのプロセスを選択する -e と等しい

e
コマンドの後に環境を表示する

l, -l
長いフォーマット。 - ( ダッシュ ) のあるなしで表示は異なる。

w, -w
出力幅を広げる、このオプションを2つ指定すると、幅の制限がなくなる。
ps l
UID   PID  PPID CPU PRI NI      VSZ    RSS WCHAN  STAT   TT       TIME COMMAND
  501   352   348   0  31  0  4334328    952 -      S+   s000    0:00.18 -zsh

 ps に l オプションを指定すると PID だけでなく PPID ( 親プロセスのID ) も表示される。