授業資料/03 の変更点


#contents

//  第 3 回 -- プロセス,ジョブ

* Process and Job: プロセスとジョブ, マルチタスクについて [#fc9f1c71]

gui では直感的に理解できるマルチタスクも cui ではその状態が見えにくい.
// そのため,cui 初心者状態ユーザはせっかくのマルチタスクを生かせずに dos のようなシングルタスク環境とあまり変わらない状態で unix cui 環境を利用していることがまま見受けられる.
// こうした状況は時間の無駄といえる.
そこで,ユーザによるプロセスやジョブの制御を学ぼう.
// このプロセスとジョブだが,ユーザから見るとシームレスに繋がっており,区別が見えにくい.
まずプロセス制御とジョブ制御を明確に区別して学習し,理解してからそれらを使いこなすことを目的とする.

: マルチタスクとは |
同時に複数の処理をこなすこと,もしくはそれらの処理.
// コンピュータの場合,この処理とはだいたいプログラムのことだと思ってよいだろう.
&br;
今や普通に触れる OS のほとんどはマルチタスクなシステムである.
// としては,unix, windows, mac os などが挙げられるだろう.
// 逆に,dos などはシングルタスクシステムであり,(実質的には)一度に一つのプログラムしか動作させられない.
// &br;
// unix システムがマルチタスクシステムであることから,以下に解説するプロセス & ジョブ制御が必要となってくる.

* Process: プロセスとは [#h2f0b51a]

: プロセス |
// unix のようなマルチタスクシステムでは,同時に多くのプログラムが動作している.
// しかし,
一つのプログラムを良くみると様々な機能から構成されている.
そこで,こうした機能毎に動作を分離することで,様々な処理を能率良く,かつより分かりやすく安全に行なうことができる.
&br;
この時の,コンピュータ上で自立して動作する最小単位をプロセスと言う.
言い換えると,一つのプログラムは複数もしくは一つのプロセスからなる.
&br;
プロセスをさらに細分化した「スレッド」という概念もあるが
// 細かい単位として,動作時間やリソース(Resource, 資源)をさらに効率的に用いるために,
自立して動作しないものであり,ここでは触れない.
// &br;&br;
// よって,コンピュータの動作は,「多くの(ほぼ独立な)プロセスが同時に動作している」と理解すればよい.
: プロセス制御 |
unix 上ではほぼ常に多数のプロセスが(擬似的に)同時に動作している.
この時,個々のプロセスを一時停止ないしは停止したり,優先順位を上下させたりすることができると何かと便利だ.
// 逆にプロセス制御が出来ないと,トラブルが起きたときなどにシステムを停止,再起動するぐらいしか対応方法がなく,不便である.
// &br;
実際にそのようにプロセスの動作をその場で変えることをプロセス制御という.
// とシステムそのものの動作を独立にするために提供される手段,
// それが
// &br;
// また,プロセス制御を適切に行なうことにより,システム全体のパフォーマンスを上げることも可能である.
: プロセスの親子関係 |
unix では,全てのプロセスはなんらかのプロセスによって生成される.
これを「親子関係」と見なして,もとのプロセスを新しいプロセスの
「親プロセス」と呼ぶ.
&br;
「子プロセス」の「死体処理(ゾンビ状態のプロセスを消滅させること)」をするのは親プロセスの役目であるため,
子プロセスが親プロセスよりも先に死ななければいけない.
&br;
よって,何らかの理由により親プロセスが先に死んでしまった場合,
ゾンビになった子プロセスの処理が難しくなることがある.

** To know the status of processes: ps command: プロセスの状態を知る: ps コマンド [#c2d02b07]

プロセスの状態を知るには,''ps'' コマンドを用いる.

オプション無しだと「自分が実行した」プロセスのみが表示される.
// 他人が実行しているプロセスなども見たいときは,
// 適切なオプションを用いる必要がある.

お勧めのオプションは,システム全体のプロセスがわかり,かつ, BSD でも
linux でも cygwin でも有効な ''axu'' である((ただし,cygwin システムはほとんどプロセスを持っていないため,''ps axu'' では寂しい結果しか表示されない.cygwin では ''ps -W'' とすると,MS-Windows のプロセスも表示されるので,cygwin ではこの方が良いかもしれない.)).
''ps␣axu'' と打ち込んでみよう.
// ただし,Windows のプログラムについても見たければ,''ps␣-aW'' としてみるとよい.
より詳しい情報を知りたいときは,''man ps'' でオンラインマニュアルをひこう.

*** examples of ps command: ps コマンドの使い方による違いの例 [#af563fd7]

: ''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  1504  352 ?        S     2010   0:01 init [2]
  root         2  0.0  0.0     0    0 ?        SN    2010   0:00 [ksoftirqd/0]
  root         3  0.0  0.0     0    0 ?        S<    2010   0:00 [events/0]
  …略…
  daemon   10220  0.0  1.2 16972 11564 ?       S    23:29   0:00 /usr/local/apache2/bin/httpd -k start
  paoon    10221  0.0  0.0  2496  848 pts/0    R+   23:30   0:00 ps axu

ps コマンドで見られる情報のうち,重要なものだけ解説しておこう.

: USER |
ユーザ名.
そのプロセスの利用者.
&br;
注) 通常ユーザは,自分が利用しているプロセスしか制御できない.
: PID |
プロセス ID.
各々のプロセスに固有な番号. 
// 人間で言えば,個人名である.
プロセスの制御はこの PID を基本として行なわれる.
: %CPU | 
cpu 利用率.
: %MEM |
メモリ使用率.
: tty |
制御端末名.
そのプロセスがどの「端末」に属しているかを示す.
: STAT |
プロセスの状態. 
&br;
&ref(/materials/warning.png); トラブル時に役に立つ!
&br;
表示文字の意味は以下の通り(主要なもの).
&br;
&br;
''S'' …
プロセスは sleep 状態(キーボード入力完了待ち)である.
&br;
''R'' …
プロセスは実行可能状態.
&br;
''D'' …
プロセスはディスク入出力完了待ちである.
&br;
''T'' …
プロセスは停止(stop)中である.
&br;
''Z'' …
プロセスはゾンビ(zombie, "死んでいる")である.
&br;
&br;
// この stat を見ればプロセスの状態がわかる.
&color(red){T や Z という状態は異常事態を示唆する.};
また,長時間 D のままという場合も,何かおかしい可能性が高い.
: command |
コマンド名と引数

&ref(/materials/notes.png); 実習: ps コマンドを用いて,今自分が実行している複数のプロセス全てについて,その状態がどうなっているかきちんと調べよ.

** To know the status of processes: top command: プロセスの状態を知る: top コマンド [#h7428b29]

''top''
コマンドで,プロセスの状態を「動的」かつ「連続的」にみることができる.
通常は,CPU利用率の高い順にプロセスが動的に並べ替えられて表示されるが,この「並べ替えに使う項目」は自由に変えることが出来る.
// &br;
// このコマンドはどちらかというと,プロセスがどれくらい「重い=負荷が高い」のかをみるために使われる.

&ref(/materials/notes.png); 実習: top コマンドを実行し,挙動を見てみる.また,実行中に ''?'' キーを押し,実行中に何ができるか把握せよ.


** Control of processes: launch: プロセスを制御: プロセスを作る,動作させる [#fe7e1e68]

// プロセスとは上に述べたようにプログラムを構成する単位であるため,
ユーザから見たとき,プログラムを実行することは即ちプロセスを生成することである.
// &br;
逆に,プログラムの実行が完全に終わったときには,
そのプログラムによって作られたプロセスは全て消滅したことになる.

** Control of processes: change of priority: プロセスを制御: プロセスの優先度を変更する [#p3661f57]

プロセスには優先順位があり,優先順位が高い方がより先に実行されるようになっている.
この仕組みにより,様々なプロセスが同時に動作しても人間にとって快適に扱えるようになっている.

*** index of priority: 優先順位を示す指標 [#fd800db5]

: スケジューリング優先度 |
0 〜 127 の数字で,小さい方が優先される.
: nice 値 |
この数字とプロセスの性格などから, 上の優先度が決定される. -20 〜 20 程度の数字で,小さい方が優先される.
デフォルトは 0.

ちなみに,プロセスの優先度と nice 値を見るには,
''ps l'' (← 小文字のL(エル))
とするのが簡単である.
表示カラムのうち,''PRI'' が優先度(Priority), ''NI'' が nice値 である.

*** change of priority: 優先順位を変更する [#t28f5448]

: ''nice'' |
プログラム起動時に nice 値を決定するコマンド.
&br;
&ref(/materials/warning.png); csh 系のシェルには nice コマンドが組み込まれていることがあり,システムに既に存在する nice コマンド(/bin/nice)と混同しないように! どちらも働きは同じだが使い方は異なるため,使うときは必ずオンラインマニュアルで調べよ.
&br;
&br;
&ref(/materials/Gnome-Preferences.png); hoge というプログラムを,
通常より nice 値を 10 大きくして(= 優先順位が下がる)起動するときは
''/usr/bin/nice&#9251;hoge''
とすればよい(/usr/bin/nice コマンドはデフォルトで 10 だけ nice値を上げる).
: ''renice'' |
既に動いているプロセスの nice 値を「増やす」=「優先順位を下げる」.
&br;
動作中のプロセスのせいでコンピュータの反応が鈍くなるなどの場合に,
プロセスの優先度を下げて作業を快適にする,等の目的で用いる.

&ref(/materials/warning.png); 通常ユーザはプログラムの優先順位を下げることしか出来ないが,スーパーユーザは優先順位を上げられる.

** Control of processes: termination: プロセスを制御: プロセスを終了させる [#r51a7e26]

unix のプロセスには「プロセス間通信」といってプロセス同士が通信する仕組みが備わっている.
このプロセス間通信のうち,メッセージを伝えるだけの機能を持つものとして「シグナル」がある.
このシグナルをプロセス宛に送りつけることによって,プロセスを一時停止させたり,再起動させたり,終了させたりできる((プロセスやプログラムを強制的に終了させることを,「殺す」などと言う.)).
ただし,自分の利用しているプロセスにしかシグナルは送れない.
&br;
&br;
シグナルをプロセスに送りつけるには,
&br;
&nbsp;&nbsp;&nbsp; ''kill&#9251;-シグナル&#9251;pid''
&br;
とする.
シグナルは後述する「シグナル名」か「シグナル番号」で指定する.
&br;
シグナルを省略すると TERM (=15) を指定したことになる.

シグナルの種類は以下の通り.

| シグナル番号 | シグナル名 | シグナルの意味 |h
| 15  | TERM | TERMinate. 終了. ''kill'' コマンドのデフォルト. |
| 9 | KILL | KILL. &color(red){「強制」終了.}; このシグナルを受け取ったプロセスは終了することになっている. |
| 2 | INT | INTerrupt. 端末から割り込み(''CTRL-c'')を受けた,という意味. このシグナルを受けたプロセスは終了する. |
| 3 | QUIT | QUIT. 端末から中断終了(''CTRL-\'')を受けた,という意味. このシグナルを受けるとプロセスは(core を吐いて)死ぬ. |
| 18 | TSTP | TerminalSToP. 端末から停止(''CTRL-z'')を受けた,という意味. このシグナルを受けるとプロセスは一時停止する. |
| 17 | STOP | STOP. 強制一時停止. このシグナルを受けるとプロセスは必ず一時停止する. |
| 19 | CONT | CONTinue. 停止状態のプロセスの実行を再開する. |
| 1 | HUP | HangUP.  端末回線が切れた,ということを意味する. 普通のプロセスはこのシグナルを受けると実行を中止するが, 再起動したり特別なモードに移行するプロセスも多いので注意が必要. |

この表から分かるように,そのプロセスを確実に止めたい場合は,
&br;
''kill&#9251;-9&#9251;pid''
&br;
とするか,
&br;
''kill&#9251;-KILL&#9251;pid''
&br;
とすればよい.
&br;
&br;
&ref(/materials/warning.png); state が D のプロセスや,zombie プロセスには ''kill&#9251;-KILL'' が有効でない場合がある. こういう場合は,特に支障がなければ放置(^-^),支障がありそうだったら管理者に相談するのが良い.
&br;
&ref(/materials/warning.png); シグナル "HUP" や pid "1" "0" "-1" は特別な意味で使われることが多いので,よくわからない場合は使わないように注意すること. 
酷い目にあってみたい,という酔狂な人は自宅の unix などでスーパーユーザになって,
''kill&#9251;1'',
''kill&#9251;-KILL&#9251;-1''
などといろいろやってみよう(^-^).

** Control of processes: to ignore the termination order "HUP": プロセスを制御: 端末切断 HUP を無視させる [#v37531d4]

プログラムが動作中であっても,端末を終了したりログアウトしたりすると通常はそのプログラムは終了してしまう.
これは,そのプログラムを起動した端末環境が,終了する直前にそのプログラムに対して上の
''HUP''
シグナルを送っているためである.
&br;
&br;
しかし,大量の計算をするときなど,
「ログアウトした後もプログラムは動きつづけたままでいて欲しい」
ということがある.
// &br;
こうしたときには,
''nohup''
コマンドを用いて
''nohup&#9251;コマンド名''
としてプログラムを起動すると,ログアウトしてもこのプログラムが動作し続けるようにできる.
&br;
&br;
&ref(/materials/warning.png); コマンドを指定しないでただ
''nohup''
としてしまうと,それ以降のコマンド全てが nohup 扱いになりトラブルを引き起こす可能性が高いので,こうしないように.

// あと,
// ''nohup''
// コマンドを用いる際は,nohup 指定をしたプログラムの動作によって
// 他のユーザに迷惑がかからないように留意すること.
// &br;
// 例えば,nohup 指定をしたプログラムが CPU に大きな負担をかけるために,
// そのマシンを使う他のユーザが「このマシンは遅くて使えねー」ということ
// がないように,ということである.
// &br;
// ちなみに,こういうときは事前に
// ''nice''
// コマンドなどで該当プログラムの優先順位を下げておけばよい.

&br;&br;
&ref(/materials/notes.png); 実習: 次の手順でプロセス制御を試してみよ.
+ 端末中で ''emacs&#9251;-nw'' と入力して emacs を起動する.
+ emacs が起動している状態で ''CTRL-z'' として,emacs を停止状態にする(''CTRL-z'' や停止状態の説明は後述).
+ ''ps'' コマンドを試してみて,emacs の存在とその状態を把握する.
+ ''top'' コマンドを試してみて,emacs の存在とその状態を把握する.
+ ''ps'' コマンドで emacs の PID を把握し,''kill'' コマンドを用いて emacs を強制終了させる.
+ ''ps''コマンドで emacs が存在しない(強制終了したため)ことを確認する.


* Job: ジョブ [#n167f3c8]

ジョブとは,(シェルから見た)コンピュータ上で実行される実態の単位の概念で,
「一連の仕事をしている(複数の)プロセス」
のことである.
&br;
まあ簡単に言えば,シェルで命令した「(一行分の)命令の固まり」であり,
人間にとって一つの処理と見なせるもの,と思えばよい.
シェルの history コマンドで「一回分」のコマンドと思ってもよい.

** Why do you introduce the new concept "job"? 既にプロセスという概念があるのに, なぜわざわざ 新しくジョブという概念を持ち込むのか? [#mb17e88b]

プロセスというのは,あくまで「コンピュータ側から見た」概念で正確で確実だが,ユーザからはわかりにくい.
// 利用者との関係はほとんど考慮されていない.
// &br;
そこで,「ユーザにとっての実行単位」としてジョブという概念を定義し,
そのジョブ単位をユーザから「見えなくしたり見えるようにしたり」することで
マルチタスクを使いやすくする,というのがジョブという概念の根底に流れる思想である.

** Foreground and background: フォアグラウンド,バックグラウンド [#ocbdd59e]

シェルは人間と「対話的」に動作するため,そのまま複数のプログラムを同時に動作させるわけにはいかない.
// とキーボードの入力等が混乱するのはミエミエである(^-^).
&br;
// しかし,マルチタスクシステムである unix であるのに,
// シェル中では同時に複数のプログラムを使えないというのも意味がない.
そこで,「人間と対話しながら作業するジョブを一つだけ」と
「そうでないジョブ(複数)」
をわけることでマルチタスクを可能としている.

&ref(./jobs.png);
&ref(./jobs.png,150%);


: フォアグラウンド |
シェルを通じて人間からのキーボード入力を受けるジョブをいう.
つまり,通常使っている状態のジョブはフォアグラウンドにいるのである.
&br;
&ref(/materials/warning.png); 端末1つにキーボードは1つしかないので,フォアグラウンドジョブは端末1つにつき,1つしか存在できない.
: バックグラウンド |
人間のキーボード入力を受けられない状態で動作している時,そのジョブは
「バックグラウンドで動作している」と言う.
この状態で動作するジョブは複数あってもよい.
: 停止状態 |
起動はしているが,動作を停止している状態.
&br;
フォアグラウンドにもバックグラウンドにいられなくなったジョブが
強制的にこの状態に移されることもある.
また,ジョブをフォアグラウンドからバックグラウンドへ持っていくときの途中の状態としても用いられる.

** To know the status of jobs: ジョブの状態を知る [#sce7b72b]

そのシェルから見たときにどれだけのジョブがどういう状態にあるかは,
&br;
''jobs''
&br;
コマンドで知ることができる.
&br;
&br;
&ref(/materials/Gnome-Preferences.png); ''jobs'' コマンド 実行例.

 [1]  - 終了                          ls --color=auto -Fga -l |
        中断                          less
 [2]  + 中断                          emacs

この表示は左から,
&br;
''ジョブ番号   状態   コマンドと引数''
&br;
というリストになっている. 
ジョブ番号に「+」がついているのは,ジョブ操作コマンドのデフォルトの対象がこれであることを意味している.
(だいたいは一番大きい番号だ)
&br;
&br;
ちなみに,この例では二つのジョブが「中断」状態,つまり「停止状態」であることがわかる.

&ref(/materials/notes.png); 実習: 文字端末中で ''emacs&#9251;-nw&#9251;&amp;'' と何度か入力するなどして, ''jobs'' コマンドの様子を試してみよ.


** Control of jobs: ジョブ制御 [#kb0ff017]

ジョブ制御とは,ジョブを三状態のある状態から他の状態へと移動させることや,
プロセス制御と同じくジョブを「殺したり」することを言う.

ジョブには大まかにいって上に載せた図のような三つの状態がある.
図中にあるようなコマンドを用いてジョブの状態を変遷させることが
ジョブ制御の中心となる.
&br;
詳細は以下の通り.

** Control of jobs: launch: ジョブ制御: ジョブを作る [#kf68362e]

シェルを通じてプログラムを実行したとき,
シェルに投入された一塊のコマンド(群)がジョブとして生成される.
この時にジョブがどの状態に行くかだが,次のようになっている.
&br;
&br;
''通常はフォアグラウンド状態になるが,起動時にオプションで ''&amp;'' をつけるとバックグラウンド状態になる''
&br;
&br;
&ref(/materials/Gnome-Preferences.png); 実行例: window system が動作しているときに 端末中で ''emacs&#9251;&amp;'' とすると,emacs が「別窓で」起動するのが見られるが,これがそうである.

** Control of jobs: from background to foreground: ジョブ制御: バックからフォアへ [#radbc879]

: ''fg&#9251;%ジョブ番号'' |
そのジョブ番号をもつジョブをフォアグラウンドへ移す(入出力を人間相手にする).

&ref(/materials/warning.png); ジョブを フォア → バック に直接移す方法は無い.フォア → 停止 → バック と経由する方法( ''CTRL-z'' → ''bg&#9251;%ジョブ番号'' というコンボ)があるのでそちらを使おう.

** Control of jobs: between foreground and suspended: ジョブ制御: フォア ←→ 停止 [#m1660e8a]

: ''CTRL-z'' |
フォアグラウンドジョブを停止状態にする.
&br;
ただし,シェルそのものだけはこれで停止しないようになっている(例外).
&br;
シェルを停止したい場合は,
''suspend''
コマンド.
: ''fg&#9251;%ジョブ番号'' |
そのジョブ番号をもつジョブをフォアグラウンドへ移す(稼働状態にする).

** Control of jobs: between suspended and background: ジョブ制御: 停止 ←→ バック [#o5b77078]

: ''bg&#9251;%ジョブ番号'' |
そのジョブ番号をもつジョブをバックグラウンドに移す(動作させる).
: ''stop&#9251;%ジョブ番号'' |
そのジョブ番号をもつジョブを停止状態にする(一時停止).

** Control of jobs: to kill them: ジョブ制御: ジョブを殺す [#b9f2e9a1]

フォアグラウンドジョブ,即ち,人間と対話しながら動作しているジョブは
''CTRL-c'' などで殺すことができる.
これは
[[&ref(/materials/JNorth_arrow-right-sm.png); 資料01 コマンド操作の基本>授業資料/01#BasicOfCommandOperation]]
でも示した通りである.
&br;
ただし,シェルそのものだけはこれで死なないようになっている(例外).
&br;
&br;
そうでないジョブ(他の状態にあるジョブ)は,上の
''jobs''
コマンドでそのジョブ番号を調べて,
&br;
''kill&#9251;%ジョブ番号''
&br;
とすればそのジョブを殺すことができる.

&ref(/materials/notes.png); 実習: 次の手順でジョブ制御を試してみよ.
+ ''touch'' コマンドを用いてファイルを新しく作る.
+ 作ったファイルを 端末中で vi か emacs で編集し(''ジョブの投入''),適当に数行書き込む.
+ vi or emacs を終了せずに,停止させることでシェルへ戻る(''ジョブの停止'').
+ ''less'' コマンドを用いて編集したファイルを見る(''ジョブの投入 &amp; 停止'').
+ ''date'' コマンドを用いて日時を調べて…(''ジョブの投入 &amp; 停止'').
+ ''fg'' コマンドを用いて vi or emacs へ戻り(''停止ジョブをフォアグラウンドへ'')
+ 先ほど調べた日時を書き込んでから, vi or emacs を終了(''ジョブの停止'').
+ 再び, ''less'' コマンドを用いて編集したファイルを見て,先ほどの日時書き込みが保存されていることを確認(''ジョブの投入 &amp; 停止'').


* Report: レポート [#w34e7c2e]

以下の課題について能う限り賢明な調査と考察を行い,
&br; 
''AppliedMath7-Report-03''
&br;
という題名をつけて e-mail にて教官宛にレポートとして提出せよ. なお,レポートを e-mail の代わりに TeX で作成した書面にて提出してもよい.  

** Exercises: 課題 [#c6c19d23]

+ 本資料の実習部分をすべて行い,それについて「きちんと」報告せよ(やりました,などだけというのはダメだよね).
+ ジョブを投入して停止状態にする方法を複数述べよ.
&br;
また,これらの作業を実際にやってみよ.
ただし,この操作の様子を
''script''
コマンドで記録しておいて,その記録を提出する形で報告すること.
+ ''kill''
でもプロセスが殺せない場合が何通りか考えられる.
そのうち,3種類を挙げてきちんと解説せよ.
+ ジョブを あわせて 5つほど投入し,全てが共存する状態にし,
三状態を自在に遷移させよ. 
&br;
ただし,この操作の様子を
''script''
コマンドで記録しておいて,その記録を提出する形で報告すること.

* about Icons, ClipArts [#l279b982]

For details, see [[&ref(/materials/JNorth_arrow-right-sm.png); this>materials]].

// ━┃┏┓┛┗┣┳┫┻╋


// コマンドライン入力は「行頭を > で始める」.
// コマンドライン出力は「行頭をブランクで始める」.

// 実習アイコン
// &ref(/materials/notes.png); 

// 注意アイコン
// &ref(/materials/warning.png);

// Link アイコン
// &ref(/materials/JNorth_arrow-right-sm.png); 

// OK アイコン
// &ref(/materials/OK.png);

// NG アイコン
// &ref(/materials/NG.png);

// サンプルアイコン
// &ref(/materials/Gnome-Preferences.png);

// 大文字での強調 
// CENTER:&size(24){''ほげほげ''};

// programu source 表記
// #highlighter(language=ruby,number=on,cache=on){{}}

// パイプ
// &brvbar;