unix はマルチタスクシステムであり,
ユーザはその恩恵を最大限に利用するべきである.
しかし,gui では直感的に理解できるマルチタスクも
cui ではその状態が見えにくい.
そのため,cui 初心者状態ユーザはせっかくのマルチタスクを生かせずに
dos のようなシングルタスク環境とあまり変わらない状態で
unix cui 環境を利用していることがまま見受けられる.
こうした状況は大いなる時間の無駄といえる.
そこで今回の授業では,ユーザがプロセスを制御するとはどういうことかを学び,
cui 環境でも大いにマルチタスクの恩恵を受けられるようになることを目指す.
ユーザから見た場合,プロセス制御とジョブ制御はほとんどシームレスに繋がっており,
区別する必要は余りない.
しかしその為にかえって理解が深まらない可能性は高い.
そこでプロセス制御とジョブ制御を明確に区別して学習し,理解してから
それらを使いこなすことを目的とする.
プロセスとは上に述べたようにプログラムを構成する単位であるため,
ユーザから見たとき,プログラムを実行することは即ちプロセスを生成することである.
逆に,プログラムの実行が完全に終わったときには,
そのプログラムによって作られたプロセスは全て消滅した,ということになる.
プロセスの状態を知るには,ps
コマンドを用いる.
ただし,そのままだと「自分が実行した」プロセスしか表示されない.
他人が実行しているプロセスなども見たいときは,
適切なオプションを用いる必要がある.
お勧めはとりあえず ps -axu
である.
より詳しい情報を知りたいときは,man ps
でオンラインマニュアルをひくこと.
注1) 便宜のために記しておくと,ps -O キーワード
でそのキーワードに相当する情報を二番目のヘッダとして得られる.
注2)
ps
の他に
top
というコマンドでもプロセスの様子を見ることができる.
面白いので一度実行してみるとよい.
コマンド | 結果例 |
---|---|
ps
|
PID TTY TIME CMD 29452 pts/0 00:00:00 sh 29475 pts/0 00:00:00 tcsh 31982 pts/0 00:00:00 ps |
ps -axu
|
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 1116 64 ? S May22 0:05 init [5] root 2 0.0 0.0 0 0 ? SW May22 0:00 [kflushd] root 3 0.0 0.0 0 0 ? SW May22 0:00 [kupdate] root 4 0.0 0.0 0 0 ? SW May22 0:05 [kswapd]…略… ot-026fd 29452 0.0 0.8 1888 1132 pts/0 S 15:07 0:00 -sh root 29455 0.0 0.0 0 0 ? SW 15:07 0:00 [rpciod] root 29456 0.0 0.0 0 0 ? SW 15:07 0:00 [lockd] ot-026fd 29475 0.0 1.0 2332 1328 pts/0 S 15:07 0:00 -csh root 31202 0.0 7.3 35344 9412 ? S 16:36 0:02 /etc/X11/X -au root 31203 0.0 0.7 3188 952 ? S 16:36 0:00 /usr/bin/gdm - root 31211 0.0 3.6 6956 4684 ? S 16:36 0:00 ruby /etc/ecip root 31212 0.0 0.9 2320 1216 ? S 16:36 0:00 /usr/bin/xpeng gdm 31214 0.0 2.9 6688 3756 ? S 16:36 0:00 /usr/bin/gdmlo ot-026fd 31984 0.0 0.6 2460 796 pts/0 R 17:45 0:00 ps -axu |
ps コマンドで見られる情報のうち,重要なものをいくつか解説しておこう.
キーワード | 意味 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
pid |
プロセス ID.
各々のプロセスに固有な番号.
人間で言えば,個人名である.
プロセスの制御はこの PID を基本として行なわれる. |
||||||||||||
user |
ユーザ名.
そのプロセスの利用者.
注) 通常ユーザは,自分が利用しているプロセスしか制御できない. |
||||||||||||
%cpu | cpu 利用率. 通常は数〜数十パーセント程度であり, この数字が異様に高い(100% に近い)状態が長時間続き, かつ,負荷の高いプロセスを走らせているつもりがなければ, そのプロセスが暴走している可能性がある. | ||||||||||||
%mem | メモリ使用率. これも暴走しているプロセスでは大きくなる傾向がある. | ||||||||||||
tty | 制御端末名. そのプロセスがどの「端末」に属しているかを示す. | ||||||||||||
stat |
プロセスの状態.
一文字ずつある状態を意味する.
主要なものを示しておこう.
この stat を見ればプロセスの状態がわかる. T や Z という状態は(思い当たる節がなければ)何か異常が起こっていることを示唆する. また,長時間 D のままという場合も,何かおかしい可能性が高い. |
||||||||||||
command | コマンド名と引数 | ||||||||||||
pri | (スケジューリング)優先度. 0 〜 127 の数字で,小さい方が優先度が高い. | ||||||||||||
ni | nice 値. この数字とプロセスの性格などから優先度が決定される. -20 〜 20 程度の数字で,小さい方が優先度を高くできる. デフォルトは 0. |
プロセスには「優先順位」というものがあり,
優先順位が高い方がより先に実行されるようになっている.
この仕組みにより,様々なプロセスが同時に動作しても
人間にとって快適に扱えるようになっている.
このプロセスの優先順位を意識的に変更する方法があり,
これを用いると unix をより快適に使えるようになるだろう.
ちなみに,プロセスの優先度と nice 値を見るには,
ps l
(← 小文字のL(エル))とするのが簡単だ.
コマンド名 | 解説 |
---|---|
nice |
プログラム起動時に nice 値を決定する.
注) csh 系のシェルには nice コマンドが組み込まれていることがあり, システムに既に存在する nice コマンド(/bin/nice)と混同しやすい. どちらも働きは同じだが,実際の使い方は異なるため, 使うときは必ずオンラインマニュアルで調べる必要がある. |
/bin/nice -数字 コマンド
システムの nice を用いて何かプログラムを起動する. 「数字」部分には nice 値を指定する. 通常ユーザは 0〜20 しか指定できない(つまり,優先度は下がる). |
|
renice |
既に動いているプロセスの nice 値を「増やす」=「優先度を下げる」.
動作中のプロセスのせいでコンピュータの反応が鈍くなるなどの場合に, プロセスの優先度を下げて作業を快適にする,等の目的で用いる. 一度優先度を下げたプログラムの優先度を元に戻すことは出来ない. つまり,いかなる場合でも通常ユーザは nice 値を増やすことしか出来ない. スーパーユーザだけは,nice 値を減らす,つまり優先度を上げることができる. |
unix のプロセスには「プロセス間通信」といってプロセス同士が通信する仕組みが備わっている.
このプロセス間通信のうち,メッセージを伝えるだけの機能を持つものとして「シグナル」がある.
このシグナルをプロセス宛に送りつけることによって,プロセスを停止させたり,再起動させたり,殺したりできる.
(ただし,自分の利用しているプロセスにしかシグナルは送れない)
シグナルをプロセスに送りつけるには,
kill -シグナル pid
とする.
シグナルは後述する「シグナル名」か「シグナル番号」で指定する.
シグナルを省略すると TERM (=15) を指定したことになる.
シグナル番号 | シグナル名 | シグナルの意味 |
---|---|---|
15 | TERM |
TERMinate.
終了. kill コマンドのデフォルト.
|
9 | KILL | KILL. 「強制」終了. このシグナルを受け取ったプロセスは必ず死ぬ. |
2 | INT |
INTerrupt.
端末から割り込み(CTRL-c )を受けた,という意味.
このシグナルを受けるとプロセスは死ぬ.
|
3 | QUIT |
QUIT.
端末から中断終了(CTRL-\ )を受けた,という意味.
このシグナルを受けるとプロセスは(core を吐いて)死ぬ.
|
18 | TSTP |
TerminalSToP.
端末から停止(CTRL-z )を受けた,という意味.
このシグナルを受けるとプロセスは(一時)停止する.
|
17 | STOP | STOP. 「強制」停止. このシグナルを受けるとプロセスは必ず停止する. |
19 | CONT | CONTinue. 停止状態のプロセスの実行を再開する. |
1 | HUP | HangUP. 端末回線が切れた,ということを意味する. 普通のプロセスはこのシグナルを受けると実行を中止するが, 再起動したり特別なモードに移行するプロセスも多いので注意が必要だ. |
この表から分かるように,どうしてもそのプロセスを殺したい場合は,
kill -9 pid
とするか,
kill -KILL pid
とすればよい,ということになる.
注1) state が D のプロセスや,zombie プロセスには
kill -KILL
が有効でない場合がある.
こういう場合は,特に支障がなければ放置(^-^),支障がありそうだったら
管理者に相談するのが良い.
注2) シグナル "HUP" や pid "1" "0" "-1" は特別な意味で使われることが多いので,
よくわからない場合は使わないように注意すること.
酷い目にあってみたい,という酔狂な人は自宅の unix などでスーパーユーザになって,
kill 1
,
kill -KILL -1
などといろいろやってみよう(^-^).
ジョブとは,(シェルから見た)コンピュータ上で実行される実態の単位の概念で,
「一連の仕事をしている(複数の)プロセス」
のことである.
まあ簡単に言えば,シェルで命令した「(一行分の)命令の固まり」であり,
人間にとって一つの処理と見なせるもの,と思えばよい.
# シェルの history コマンドで「一回分」のコマンドと思ってもよい.
プロセスというのは,あくまで「コンピュータ側から見た」概念である.
それは正確で確実な概念であるが,利用者との関係はほとんど考慮されていない.
そこで,「ユーザにとっての実行単位」としてジョブという概念を定義し,
そのジョブ単位をユーザから「見えなくしたり見えるようにしたり」することで
マルチタスクを使いやすくする,というのがジョブという概念の根底に流れる思想である.
シェルは人間と「対話的」に動作するのが基本であるため,
シェルの上で素直に複数のプログラムを同時に動作させるとキーボードの入力等が混乱するのはミエミエである(^-^).
しかし,マルチタスクシステムである unix であるのに,
シェル中では同時に複数のプログラムを使えないというのも意味がない.
そこで,「人間と対話しながら作業するジョブを一つだけ」と
「そうでないジョブ(複数)」
をわけることでマルチタスクを可能としている.
ジョブ制御とは,ジョブを上の三状態のある状態から他の状態へと移動させることや, プロセス制御と同じくジョブを「殺したり」することを言う.
![]() |
ジョブには大まかにいって左図のような三つの状態があり得る.
図中にあるようなコマンドを用いてジョブの状態を変遷させることが ジョブ制御の中心となる. ジョブ制御の残りの部分は,プロセス制御と同じく,
|
ユーザから見たとき,シェルを通じてプログラムを実行したとき,
シェルに投入された一塊のコマンド(群)がジョブとして生成される.
この時,後で示すようなオプションを使わなければこのジョブは自動的にフォアグラウンドジョブとして扱われる.
そのシェルから見たときにどれだけのジョブがどういう状態にあるかは,
jobs
コマンドで知ることができる.
例えば,阪大教育用計算機システムで
jobs
コマンドを実行してみると,
[1] - 終了 ls --color=auto -Fga -l | 中断 less [2] + 中断 emacsのような表示が得られる. この表示は左から,
kill, fg, bg
コマンドで
%ジョブ番号
を省略した場合にデフォルトで使われる番号がこれであることを意味している.
(だいたいは一番大きい番号だ)
フォアグラウンドジョブ,即ち,人間と対話しながら動作しているジョブは
CTRL-c
などで殺すことができる.
これは
コマンド操作の基本
でも示した通りである.
ただし,シェルそのものだけはこれで死なないようになっている(例外措置).
そうでないジョブ(他の状態にあるジョブ)は,上の
jobs
コマンドでそのジョブ番号を調べて,
kill %ジョブ番号
とすればそのジョブを殺すことができる.
注)
nice
同様,
kill
もシェルの組み込みコマンドとシステムのコマンドの両方がある.
ただし,直感的な動作の違いは余りないので気にせずに済むだろう.
xemacs &
とすると,xemacs が「別窓で」起動するのが見られるが,これがそうである.
less .bashrc
で kterm 中に less を起動するとこれはフォアグラウンドジョブである.
CTRL-z
ではシェルそのものは停止しない.
ではシェルを停止させるにはどうしたらよいか,調べよ.
HUP
シグナルを受けると実行を中止するが,これを無視させるようにするにはどうしたらよいか調べよ.