プロセスとジョブ
プロセスとは
プロセスとは、ハードディスクなどに保存されているプログラムが、コンピュータのメモリに読み込まれて実行可能な状態に
なったもののことです。私たちが作成したプログラムも、OSによってメモリに読み込まれ、プロセスとして実行されます。
OSやアプリケーションソフトウェアは、1つ以上(WindowsやLinux、サーバソフトウェアなどの多機能なソフトウェアはた
くさんの)プロセスで構成されています。
Linuxでは、現在どのようなプロセスが起動しており、どのような状態にあるか?などを確認するためのpsコマンドが提供
されています。
1. 以下の例は、ps uコマンドの実行結果です。ps uコマンドは、現在の端末で実行しているプロセスだけを表示しま
す。
$ ps u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
user01 22426 0.0 0.1 116700 3340 pts/0 Ss 12:24 0:00 /bin/bash
user01 23497 0.0 0.0 139496 1624 pts/0 R+ 13:07 0:00 ps u
<実行結果の意味>
- USER プロセスの所有ユーザー
- PID プロセス番号
- &CPU CPUの占有率
- &MEM 実メモリの占有率
- VSZ 仮想分も含めた使用サイズ(Kバイト)
- RSS 実メモリ上の使用サイズ(Kバイト)
- TTY 端末名
- STAT プロセスの状態(R:稼動中、S:一時停止中、T:終了処理中、など。
- START プロセスの開始時刻
- TIME プロセスの総実行時間
- COMMAND 実行コマンド名とパス
Ssは一時停止中のセッションリーダー、R+ はフォアグラウンドで実行中を表す)
2. ほかのユーザが実行しているプロセスも含めた、すべてのプロセスを確認する場合はps auxコマンドを実行します。すると、
実際にはOS上で非常にたくさんのプロセスが動作していることがわかります。
本コマンドは、どのプロセスがコンピュータに負荷をかけているか?メモリをたくさん使用しているのはどのプロセスか?などを
確認するときによく使用します。
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 123468 4100 ? Ss 12月26 0:10 /usr/lib/system
root 2 0.0 0.0 0 0 ? S 12月26 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? S 12月26 0:00 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S 12月26 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? S 12月26 0:00 [rcu_bh]
root 9 0.0 0.0 0 0 ? S 12月26 0:00 [rcuob/0]
root 10 0.0 0.0 0 0 ? S 12月26 0:09 [rcu_sched]
root 11 0.0 0.0 0 0 ? R 12月26 0:14 [rcuos/0]
root 12 0.0 0.0 0 0 ? S 12月26 0:03 [watchdog/0]
root 13 0.0 0.0 0 0 ? S< 12月26 0:00 [khelper]
root 14 0.0 0.0 0 0 ? S 12月26 0:00 [kdevtmpfs]
root 15 0.0 0.0 0 0 ? S< 12月26 0:00 [netns]
root 16 0.0 0.0 0 0 ? S< 12月26 0:00 [perf]
root 17 0.0 0.0 0 0 ? S< 12月26 0:00 [writeback]
root 18 0.0 0.0 0 0 ? S< 12月26 0:00 [kintegrityd]
(以下省略)
3. 特定のプロセスの状態だけを見たい場合は、以下のようにパイプラインを使用すると便利です。
$ ps aux | head -1 && ps aux | grep 条件
==========
例)$ ps aux | head -1 && ps aux | grep bash
※「条件」には、右端のCOMMAND列に表示される名前や、1列目のUSER列に表示されるユーザ名など、条件に使
用したいものを指定します。
上記の例では、ps auxコマンドの実行結果の1行目(タイトル行)と、bashという文字列を含む行を表示してい
ます。
==========
4. プロセスは、別のプロセスを生成することもできます。生成した側のプロセスを親、生成された側のプロセスを子プロセスと
いいます。
プロセスの親子関係を表示する場合は、psコマンドのfオプションを使用します。
以下の例では、stressというコマンドを実行します。stressコマンドは、指定した数のプロセスを子プロセスとして起動する
ので、このような状態で表示されます。
$ stress --cpu 3 &
$ ps f
PID TTY STAT TIME COMMAND
28693 pts/0 S+ 0:00 bash
32219 pts/1 Ss 0:00 /bin/bash |シェル(bash)が元々の親プロセス
32370 pts/1 S 0:00 ¥_ stress --cpu 3 |stressの親プロセス
32372 pts/1 R 0:00 | ¥_ stress --cpu 3 |stressの子プロセス
32373 pts/1 R 0:00 | ¥_ stress --cpu 3 |stressの子プロセス
32374 pts/1 R 0:00 | ¥_ stress --cpu 3 |stressの子プロセス
32377 pts/1 R+ 0:00 ¥_ ps f |ps fもbashの子プロセス
27649 pts/0 Ss 0:00 /bin/bash$ ps aux
フォアグラウンドとバックグラウンド
Linuxにはジョブ(job)という概念があります。
プロセスは、カーネルから見た処理の単位ですが、ジョブはシェルから見た処理の単位で、コマンドやプログラムがまとまった、ひ
とかたまりの処理のことを指します。たとえば、上図のように複数のコマンドをパイプラインでつなげて連続した処理を行っ
た場合、プロセスは3つですが、ジョブとしては1つです。
Linuxでは、jobsというコマンドをジョブの確認に利用できます。
LinuxやWindowsは、マルチタスクのOSです。マルチタスクOSとは、複数のジョブやプロセスを並行して実行できる仕組みを
持ったOSのことです。
マルチタスクOSでは、フォアグラウンドとバックグラウンドという用語をよく使用します。
フォアグラウンド( foreground:前景)ジョブ/プロセス/アプリケーションとは、前面に表示され、現在操作できるアクティブ
な状態となっているプロセスやジョブのことです。GUIの場合は、前面に表示され、操作中のウインドウがフォアグラウンドである、
と考えればよいでしょう。
バックグラウンド(background:背景)ジョブ/プロセス/アプリケーションとは、フォアグラウンドの裏で動作しているプロセス
やジョブ、アプリケーションのことです。
バックグラウンドプロセス(ジョブ)としてプログラムを起動する場合は、コマンドの末尾に&を付けます。
たとえば、sleepというコマンドをバックグラウンドで実行する場合は以下のように指定します。
この場合は、すぐに端末に別のコマンドが入力できます。
$ sleep 100 & 100秒間待機状態にするコマンドをバックグラウンドで実行
ジョブとしてはどのように表示されるかを確認しましょう。
$ jobs
[1]+ 実行中 sleep 100 &
一方、&を付けずにプログラムを起動すると、端末ウインドウはフォアグラウンドに切り替わってしまうため、そのプログラムを終了
するまで(この例ではsleepコマンドの実行が終了するまで)端末ウインドウは、ほかのコマンドを受け付けなくなります。
$ sleep 100 100秒間待機状態にするコマンドをフォアグラウンドで実行
フォアグラウンドで実行されているものを中断する場合は[Ctrl] + [c]キーを押します)。
[Ctrl] + [c]キーを押す
[1]+ 終了 sleep 100
ジョブ・プロセスの強制終了
コンピュータを使用していると、ジョブやプロセス、アプリケーションプログラムが不具合などにより操作できない状態に陥るこ
とがあります。このような状態を、「フリーズする」、「固まる」といいます。フリーズしたジョブやプロセス、アプリケーションプログ
ラムは、強制的に終了させる必要があります。
フォアグラウンドジョブは、キーボードの入力待ち状態なので、[Ctrl]+[C]キーで終了できます。
バックグラウンドジョブは、キーボード入力を受け付けていないので、killコマンドで終了させる必要があります。また、killコ
マンドは、プロセスの終了もできます。
1. フォアグラウンドジョブの終了
$ sleep 100 100秒間待機状態にするコマンドを実行
(フォアグラウンドで実行されるため端末ウインドウではほかのことができなくなる)
[Ctrl]+[c]を押すと中断してプロンプトに戻る
2. バックグラウンドジョブの終了
$ sleep 100 & sleepをバックグラウンドジョブとして起動
$ jobs ジョブの一覧を表示し、job番号を確認
$ kill %1 [Ctrl]+[c]では終了できないので、確認したjob番号を指定し、sleepを強制終了
3. プロセスの終了
$ sleep 100 & sleepをバックグラウンドジョブとして起動
$ ps プロセスの一覧を表示し、 sleepのプロセスID(PID)を確認
$ kill PID 確認したPIDを指定し、sleepを強制終了
現在起動しているジョブをすべて終了し、jobsコマンドで実行中のジョブが何も表示されなくなったことを確認しましょう。
デーモン(Daemon)、サービス
通常、プロセスは必要に応じて起動、実行され、処理が終わると終了します。
しかし、OSの起動時に自動的に起動され、だれがログインしているか?ログオフしたか?に関係なく、OSが終了するま
でバックグラウンド(裏)で動作し続けるプロセスも存在します。このようなプロセスのことを、デーモン(Daemon:守
護神)またはサービスといいます。
たとえば、Webサーバやデータベースサーバなどは、いつユーザが要求を送信してくるかわからないため、常に起動し、待
機させておく必要があります。このようなプロセスがデーモンです。多くのデーモンは、名前の最後尾に "d" が付きます。
代表的なデーモンには、指定されたスケジュールに従ってタスクを実行するcrond、 Web サーバ機能を提供する
httpd、などがあります。
1. psコマンドを実行し、現在の端末で実行されているプロセスを確認します(ここにはデーモンは表示されません)。
$ ps
PID TTY TIME CMD
26993 pts/0 00:00:00 bash
30653 pts/0 00:00:00 ps
2. Linuxで動作しているすべてのプロセスを表示します(デーモンを含む、大量のプロセスが表示されます)。
$ ps aux ※コマンドのオプションについては前ページで確認してください
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 123468 4100 ? Ss 03:42 0:05 /usr/lib/systemd/syste
root 2 0.0 0.0 0 0 ? S 03:42 0:00 [kthreadd]
(以下省略)
マルチタスク
現代のコンピュータでは、複数のプロセスがOS上で動作し、OSがプロセスを切り替えながら処理を実行しています。
たとえば、Webブラウザを起動し、Webページからファイルをダウンロードしながら、Microsoft Wordで報告書を
作成し、Excelで作成したグラフをWordにはりつける、ということを当たり前のこととして行っています。
このように複数のプロセスを同時に実行する動作のことを「マルチタスク」といいます。マルチタスクは、現代のOSの
標準的な機能です。
このようなマルチタスクの動作は、実際には上図のように、プロセスやスレッド(後述)を切り替えて実行することで
実現されています。
切り替え動作は非常に短い間隔で行われるため、ユーザからは複数のプログラムが同時に動作しているように見え
ます。
プロセスとスレッド
プログラムは、ファイルとしてハードディスクなどに保存されています。そして、起動のための操作を行うと、プログラムがメモリ
に読み込まれ、実行可能な状態(プロセス)になります。
1つのプログラムが、いくつのプロセスとして動作するかは、プログラムによって異なります。このため、一般的には、プログラ
ムは一つ以上のプロセスで構成される、という言い方をします。
プロセスはプログラムの実行単位(メモリなどの割り当て単位)ですが、実際にCPU上で実行されるのは、スレッド
(thread)単位です。スレッドは、プロセスの中の実行単位で、OSのプロセススケジューラ(次ページ)がスケジューリ
ングできる最小の実行単位でもあります。
複数のスレッドは、異なるコアで動作させることで、同時に並行動作させることもできます。また、スレッドによって同じプロ
セス内の複数のスレッドを、同じメモリ空間上で実行できるため、起動や切り替えのオーバーヘッドを少なくし、メモリ消費
量も軽減できます。
プロセスは、それぞれ個別のメモリ領域が割り当てられます。たとえば、lsコマンドを3つ同時実行した場合でも、各lsコマ
ンドは個別のプロセスとして扱われ、異なるメモリ領域が割り当てられるため、プロセス内部のデータが混ざってしまうこと
はありません、
また、プロセスは「実行ユーザ」が設定されており、他のユーザのプロセスを勝手に操作することはできない仕組みが提供
されています。
このように、OSは各プロセスを区別し、個別に管理する役割も担当しています。
Linuxカーネルは、各プロセスにプロセスIDという重複しない番号を起動時に割り当てて、各プロセスを識別しています。
なお、Linuxでは、プロセスは既に存在しているプロセスを元に作成するというモデルを採用しています。これを親子関係
に例えて、もとになるプロセスを親プロセス、親から作成されるプロセスを子プロセスと呼んでいます。
たとえば、端末ウインドウでlsコマンドを実行すると、シェルが親プロセス、lsコマンドのプロセスが子プロセスになります。
==============================
OnePoint
コンピュータに搭載されているCPU数の単位には、ソケット、コア、スレッドがあります。ソケットは物理的なCPUのことです。物
理的なCPUにはコアと呼ばれる実際に計算を行う頭脳部を2つ以上搭載しているものがあります。「1ソケット4コア」は4つの
コアを搭載した1つの物理CPUです。
CPUコアは、メモリからデータを取り出すときなどに待ち時間が発生します。待ち時間にほかのスレッドを実行する、ハイパース
レッディングという技術に対応している場合は、コアの数以上のスレッドを同時に処理することができます。
=============================
コア&スレッド
最近主流のCPUでは、「マルチコアプロセッサー」という“1つのCPUの中に複数のコアが入っている”のが主流となっております。
複数のコアが存在すると、複数の処理を並行で行う場合に有効です。
※現在の主流※
「クアッドコア(4コア)」「ヘキサコア(6コア)」「オクタコア(8コア)」
このコアを多く備えていれば備えているほど「同時並行で行える処理作業の数が増える」
スレッド数
「4コア8スレッド」のように、コア数と並んで表記されていることの多いスレッド数は「論理コア数」とも呼ばれており、パソコンから認識されているコア数のことを表しています。インテル社が自社のマイクロプロセッサ(MPU/CPU)製品に搭載している、一つのプロセッサコアを擬似的に二つに見せかける技術をハイパースレッディングという。
処理の切り替え(参考)
上図は、プロセスやスレッドがどのように処理を切り替えられているかを図にあらわしたものです。プロセスやスレッドは、
OSのプロセス管理機能である「プロセススケジューラ」や「ディスパッチャ」などが制御しています。
- プロセスディスパッチャ
- プロセススケジューラ
指定されたプロセスに実行権を与える(CPUを割り当てる)処理を行う
実行可能なプロセス群を監視し、どのプロセスに実行権を与えるか判断する
プロセスディスパッチャに切り替え要求を出す
各プロセスは実行優先度として、固定優先度と変動優先度を持ちます。Linuxでは、固定優先度と変動優先度の合
計が最も大きなプロセスに実行権が与えられます。ただし、特定のプロセスだけが実行され続けることが無いように、
Linuxカーネルが時間経過とともにプロセスの変動優先度を変更します。このとき、より多くCPUを利用したプロセスは、
低い変動優先度が割り当てられます。シェルのような対話型プロセスはあまりCPUを利用しないため、相対的に高い変
動優先度が割り当てられます。
たとえば、geditというテキストエディタを端末からバックグラウンドで起動した場合を例に、nice値の指定方法と確認方
法を確認します。
nice値を指定して、プロセスを起動する場合は以下のように指定します。
$ nice -19 gedit &
nice -19 geditは、geditというテキストエディタのプログラムをnice値19(ユーザが指定できる最低値)で起動していま
す。
末尾の&は、geditをバックグラウンドで起動するときに指定します。
nice値を確認する場合は、以下のように指定します。
$ ps -o pid,nice,cmd
PID NI CMD
26993 0 /bin/bash
28755 19 gedit ※ ここに注目します。確認後、geditはウインドウを閉じておきましょう。
28764 0 ps -o pid,nice,cmd
プロセスの状態遷移(参考)
プロセスには、以下の状態があります。
- 実行可能
- 実行
- スリープ
- ゾンビ
プロセスが生成されると実行可能状態になる
実行可能状態のプロセスやスレッドにCPUが割り当てられて実行される
ファイルの読み取りや書き込み、ユーザやネットワークからの要求などを待っている状態
exitしてから消滅するまでの状態
プロセスは常に処理をしているわけではありません。処理待ちをしている状態もあります。
たとえば、データをハードディスクなどから読みまたは書き込みの完了待ち、サーバがクライアントから何か要求を送信され
たときのために待機している状態、プロセス自身は早く処理したいものがあっても、ほかのプロセスの処理が終わらないた
めにCPUが空くのを待っている状態、というのもあります。
OSは、特定のプロセスだけがCPUを占有しないよう、優先順位に基づいて適切に処理対象のプロセスを切り替え
ながら、処理を行う「プロセス管理」の役割も担当しています。
また、管理者やユーザがプロセスの状態を確認し、プロセスの終了などが行えるような機能も提供します。
vmstatコマンド(参考)
vmstatは、メモリやCPU、ディスクへの読み書きなどの統計情報を表示するコマンドです。
デフォルトでは起動または再起動してからの平均値を表示しますが、vmstat 10 3 のように更新間隔や回数を
指定することで、リアルタイムに情報を表示できます。
vmstatの実行結果には、以下のような意味があります。
- procs
- memory
- swap
- io
- system
- cpu
アクティブなプロセスに関する統計
r:実行待ち状態にあるプロセス数
b:I/Oなどで待たされているプロセス数
メモリの使用量と使用可能量に関するデータ
swpd:仮想メモリー量
free :空きメモリー量(Kbyte)
buff :バッファとして用いられているメモリー量(Kbyte)
スワップに関する統計
si:ディスクからスワップインしているメモリー量(Kbyte/秒)
so:ディスクにスワップしているメモリー量(Kbyte/秒)
デバイスとの転送量
bi:ハードディスクのようなブロック型デバイスから受け取ったブロック数(ブロック/秒)
bo:ブロック・デバイスに送られたブロック数(ブロック/秒)
システム全体の割り込みおよびコンテキストの切り替えレート
in:毎秒の割り込み回数
cs:毎秒のコンテキスト・スイッチ回数
CPUの使用量の割合
us:ユーザー時間 id:アイドル時間
sy:システム時間 wa:IO待ち時間
topコマンド
topコマンドは、現在実行中のプロセスをCPU利用率が高い順に表示するコマンドです。表示はリアルタイムで更新され
ます。また、終了する場合は[q]キーを押します。
たとえば、サーバからの応答が遅くなった場合、サーバのどこに負荷がかかっているのか?それともパフォーマンス以外に原
因があるのか?などの切り分けとして、CPUやメモリを多く消費しているプロセスを確認する場合などに利用します。
topコマンドは、-nオプションで表示する回数を指定できます。例えば「top -n 2」では、1回だけ表示して終了します。
表示間隔は-dオプションで秒数を指定できます。例えば「top -d 10」では、10秒間隔で画面に表示されている結
果を更新します。
Linuxに負荷をかけるコマンドを実行し、どのようにtopコマンドに表示されるかを確認しましょう。
1. stressコマンドでCPUに負荷をかけるプロセスを、バックグラウンドで1つ起動します。
$ stress --cpu 1 &
2. topコマンドで状態を確認します(下線部に注目します)。
※CPUに負荷をかけているプロセスがリストの先頭に表示されていることが確認できます。
$ top
Tasks: 173 total, 3 running, 170 sleeping, 0 stopped, 0 zombie
%Cpu(s): 97.3 us, 2.4 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
KiB Mem : 1884508 total, 374192 free, 574664 used, 935652 buff/cache
KiB Swap: 839676 total, 839676 free, 0 used. 1086372 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31781 user01 20 0 7256 92 0 R 79.1 0.0 1:25.94 stress
2900 user01 20 0 1497716 237064 47264 S 14.6 12.6 4:29.37 gnome-shell
(以下省略)
3. [q]キーを押して、topコマンドを終了します。
4. stressプロセスは、現在もバックグラウンドで動作し続けています。killコマンドで強制終了してください。
強制終了後、psコマンドでstressプロセス(またはジョブ)が表示されないことを確認してください。
仮想メモリと物理メモリの関係
物理メモリは、コンピュータに搭載されているメモリのことです。
仮想メモリとは、物理メモリ以上にプロセスにメモリを提供する機能で、OSのメモリ管理機能のひとつです。
OSは、仮想メモリ機能によって、実際に搭載されているメモリよりも多くのメモリをプロセスが利用できるような機能
を提供しています。
仮想メモリ機能は、OSによって詳細な動作は異なりますが、一般的にはフリー(空き)メモリが少ない場合、最
近使われていないメモリ(ページ)をハードディスクのスワップ領域に退避させ、必要になったらまたメモリに読み込
むという動作をします。
物理メモリが不足していると、スワップ領域への退避と再読み込みが、頻繁に発生することになります。
メモリと比較すると、ハードディスクの読み込みや書き込み速度は非常に低速なので、スワップ領域への退避や読
み込みが頻繁に発生すると待ち時間が多く発生するようになり、結果としてプログラムの動作が遅くなるため、
vmstatなどのコンピュータのパフォーマンスを確認するためのコマンドでは、CPUだけでなく物理メモリや仮想メモリ
の利用状況も確認できるようになっています。
vmstatコマンドの表示結果のうち、以下の部分が仮想メモリに関連する項目です。
- これはダミーのリストです
- これはダミーのリストです
- memory
- swap(後述)
これはダミーのリストです
メモリの使用量と使用可能量に関するデータ
swpd:仮想メモリー量
スワップに関する統計
si:ディスクからスワップインしているメモリー量(Kbyte/秒)
so:ディスクにスワップしているメモリー量(Kbyte/秒)
章末問題(MUST)
ジョブとプロセスの違いやpsコマンドやkillコマンドについて確認します。
====================
確認には、 stressという、コンピュータに負荷をかけるコマンドを使用します。
stressコマンドは、サーバの負荷テストなどで使用するコマンドなので、停止するまではバックグラウンドでコンピュータに負荷をかけ続
けます。実際には延々と負荷をかけることの無いように、stress --timeout 60 --cpu 4(60秒間だけ負荷をかける)のようなタイ
ムアウトのオプションも併用したほうが安全です。
====================
1. バックグラウンドジョブとして、stress --cpu 4コマンドを実行してください。
2. 実行したコマンドの結果、stressコマンドがジョブとして動作していることを確認してください。
3. stress --cpu 4は、ジョブとしては1つです。psコマンドで、プロセス単位でみたときの状態を確認します。
オプション無しで、psコマンドを実行し、stressのプロセス数を確認してみましょう。
※ psコマンドを実行すると、右端にstressと表示されている行が5行表示されるはずです。
これは、stressのプロセスとしては5つ動作していることを表しています。
stress --cpu 4は、stressのプロセスを4つ起動するコマンドなので、プロセスが1つ多いように見えます。
4. psコマンドにオプションを付けて、プロセスをツリー構造で確認します。
※ ps コマンドに、あるオプションを付けて実行すると、stressプロセスがツリー構造で表示されます。
実行結果を見ると、stressの親プロセスの下に、実際に負荷をかけている4つの子プロセスが表示されています。
5. このプロセスが動作していると、無駄な負荷がかかって迷惑なので、stress --cpu 4 & のジョブを強制終了してください。
コマンド内で指定するジョブIDは適宜確認してください。
6. 最後に現在実行中のジョブとプロセスを確認し、stress --cpu 4 & が停止、もしくは停止した結果表示されなくなったことを
確認してください。