Table of Contents
Linuxのタスク処理
- 複数のタスクを同時に行うことができるマルチタスクシステム
- 複数のユーザーが同時に使用することを許容するマルチユーザーシステム
という特徴をLinuxは持っています. タスクとはシステムが行う作業のことですが, これを「プロセス」とLinuxでは呼び, OSが管理するタスクの単位として用いられています.
Def: ジョブとプロセス
ジョブとは, パイプでコマンド同士をつないだ場合など, 一つ以上のプロセスの集まりのことを言います. ジョブやプロセスは, それぞれ「ジョブ番号」と「プロセスID, PID」という固有の番号を持っている
プロセスの親子関係
あるプロセスが実行中に他のプロセスを起動した場合,
- 元のプロセスのことを親プロセス
- 親プロセスから起動されたプロセスのことを子プロセス
と言います. 親子プロセスの発生と消滅をシェルからls
commandを呼び出す例で見てみると,
sequenceDiagram
participant kernel
participant bash as bash 親プロセス
participant ls as ls 子プロセス
participant display
bash->>display: command promptの表示
display ->> bash: ls コマンドの入力
bash ->> bash: 入力コマンドの解析
bash ->> kernel: 子プロセスを依頼
kernel ->> ls: 親プロセスをコピーして, 子プロセスを生成
ls ->> ls: 処理の実行
ls ->> kernel: 実行結果をkernelへ渡し, プロセスは消滅
kernel ->> bash: 結果を渡す, 子プロセス<br>リソース開放
bash ->> display: terminalへ結果を出力 & プロンプトの表示
プロセスの監視
実行中のプロセスを表示するコマンドの代表例は以下があります
ps |
プロセス情報を表示 |
pstree |
プロセスの階層構造を表示 |
top |
プロセス情報を周期的にリアルタイムに表示 |
この中でも, ps
commandは頻繁にプロセス監視で使用します.
ps
command
Def: ps command
ps
commandはprocess statusを表示するコマンドで, デフォルトでは現在の端末で自分が起動したコマンドのプロセスが表示されます.
syntaxは
1
% ps [option]
実際にデフォルトでの挙動を確認してみると
1
2
3
4
% ps
PID TTY TIME CMD
9883 pts/0 00:00:00 zsh
24316 pts/0 00:00:00 ps
PID | プロセス識別番号 |
TTY | 端末デバイスID |
TIME | プロセスが使用した現在までの合計 CPU 時間 |
CMD | processを起動したコマンド名 |
REMARKS
TTYについて, X上で動作するxtermなどの端末アプリケーションや, telnetやsshによるログインは「仮想端末(pseudo terminal)」として「pts/番号」で表示される
ps
commandのオプション
オプション | 説明 |
---|---|
a |
端末を使用するすべてのプロセスに関する情報を表示 |
f |
プロセスの親子関係を表示 |
u |
プロセスのユーザー情報を表示 |
x |
端末を利用していない全てのプロセスを表示 |
-e |
全てのプロセスを表示 |
-A |
全てのプロセスを表示, -e と同じ |
-l |
プロセスの詳細情報の表示 |
-p PID |
指定したプロセスID(PID)の情報のみ表示 |
-C プロセス名 |
指定した名前のプロセスのみ表示 |
-w |
長い行を折り返して表示 |
システムでアクティブなプロセスをすべて表示するコマンドとして以下の2つが考えられます
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## ユーザーの全てのプロセス + 端末を利用していない全てのプロセス = 全部
% ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:01 /sbin/init splash
2 ? S 0:00 [kthreadd]
3 ? I< 0:00 [rcu_gp]
4 ? I< 0:00 [rcu_par_gp]
## 全てのプロセスを表示
% ps -e
PID TTY TIME CMD
1 ? 00:00:01 systemd
2 ? 00:00:00 kthreadd
3 ? 00:00:00 rcu_gp
4 ? 00:00:00 rcu_par_gp
前者は「STAT」という新たな情報が付与されています.
Def: ps
commandのSTAT
STATはプロセスの状態を表示するカラムで, 1文字で表示される場合と2文字で表示される場合がある
STATの1文字目 | 説明 |
---|---|
0 |
CPU上で実行中 |
D |
スリープ ( CPU放棄 ), 割り込み不可の状態 : I/O待ち |
I |
アイドル状態. プロセスは現在作成中 |
R |
実行可能 ( CPU使用中, 使用可能 ) |
S |
スリープ ( CPU放棄 ), 割り込み可能な状態 : キー入力待ち |
T |
停止状態 |
Z |
プロセス終了済み状態 : 但し、親プロセスの処理待ち |
2文字目以降の付加情報の代表例は
付加情報 | 説明 |
---|---|
< |
優先順位の高いプロセス |
N |
優先順位が低いプロセス |
s |
セッションリーダー |
l |
マルチスレッド化されたプロセス |
+ |
フォアグラウンドのプロセスグループに含まれる |
ps u
command: 実行ユーザ名や実行ユーザIDのプロセスの表示
ユーザーを基本単位としてCPU使用率やメモリ使用率などのprocess情報を表示するためのオプションとして ps u
があります.
1
2
3
4
5
6
7
8
% ps u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
kirby 2746 0.0 0.0 163476 5888 tty2 Ssl+ Sep28 0:00 /usr/libexec/gdm-x-session --run-script env GNOME_SHELL_SESSION_MODE=ubuntu /usr/bin/gnome-session --session=ubuntu
kirby 2748 1.0 0.1 25426924 87764 tty2 Sl+ Sep28 3:01 /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -novtswitch -verbose 3
kirby 2760 0.0 0.0 224088 15360 tty2 Sl+ Sep28 0:00 /usr/libexec/gnome-session-binary --session=ubuntu
kirby 9883 0.0 0.0 18936 7440 pts/0 Ss+ Sep28 0:00 /usr/bin/zsh
kirby 10494 0.0 0.0 18676 8068 pts/1 Ss Sep28 0:00 /usr/bin/zsh -i
kirby 39964 0.0 0.0 13720 3328 pts/1 R+ 01:38 0:00 ps u
USER | プロセスを実行しているユーザ名 |
%CPU | CPU使用率 |
%MEM | メモリ使用率 |
VSZ | 割り当て済みの仮想アドレス空間サイズ |
RSS | 物理メモリ使用量 ( %MEMに比例 ) |
START | プロセスの起動時刻 |
すべてのユーザーについて同じく情報を取得したい場合は
1
% ps aux
PID 1となるプロセス
Linuxでは最初のプロセスはPID 1が割り当てられます,
PID 1を確認するためには-p
, p
オプションを用います
1
2
3
4
5
6
7
% ps p 1
PID TTY STAT TIME COMMAND
1 ? Ss 0:01 /sbin/init splash
% ps -p 1
PID TTY TIME CMD
1 ? 00:00:01 systemd
CMDカラムの出力結果が異なりますが, sbin/init
はシンボリックリンクであり, 実体はsystemd
です.
1
2
% ls -l /sbin/init
lrwxrwxrwx 1 root root 20 Aug 22 06:11 /sbin/init -> /lib/systemd/systemd*
なお, Linuxでは常にsystemd
の実行から始まります.
REMARKS
PIDの設定最大値は以下のコマンドによって確認できます
1
2
% cat /proc/sys/kernel/pid_max
4194304
最大値に達すると, 再び1から順番に, その時点で使用されていないPIDが割り振られます.
プロセスの制御
プロセスを制御する信号はシグナルと言います.
Def: シグナル
シグナルとは, 割り込みによってプロセスに得敵の動作をするように通知するための仕組み. 通常, プロセスは処理を終えると自動的に消滅するが, プロセスに対してシグナルを送信することで外部からプロセスを終了することができる.
Linuxではkill
コマンドやkillall
コマンドを使用し, プロセスに対してシグナルを送ります. 送信可能なシグナルの代表例は以下,
シグナル名 | シグナルID | 説明 |
---|---|---|
HUP | 1 | ハングアップ(端末との接続が切断) |
INT | 2 | キーボードからの割り込み, Ctrl + c |
QUIT | 3 | キーボードからのプロセスの中止 |
KILL | 9 | 強制終了 |
TERM | 15 | 通常終了 |
CONT | 18 | 一時停止中のプロセスを再開 |
STOP | 19 | 一時停止, Ctrl + z |
kill
command
1
% kill PID
上記のコマンドによってプロセスを通常終了させることができます.
kill
commandが送るシグナルのデフォルトは SIGTERM (15)
です.
そのため下記のコマンドはすべて同じ挙動となります
1
2
3
4
5
6
7
8
9
10
11
## optionなし
% kill 300
## シグナル名指定
% kill -TERM 300
% kill -s SIGTERM 300
% kill -s TERM 300
## シグナルID指定
% kill -15 300
% kill -s 15 300
強制終了(SIGKILL)と通常終了(SIGTERM)の違い
kill
commandが使用するデフォルトのシグナルであるSIGTERM (15)
は, プロセスを終了する前に
アプリケーションごとに必要なクリーンアップ(終了処理)を行ってから, 自分自身でプロセスを終了します.
クリーンアップでは以下のような処理を通常行います
- リソースの開放
- ロックファイルの削除
プログラムの動作に異常が発生して正常終了できない場合, SIGKILL (9)
を使用して強制終了させますが,
ファイルの破損などシステム障害が発生する可能性があるので最終手段ということに留意が必要です.
Column: キーボードからの割り込み
Ctrl + c
で送信されるシグナルは, キーボード操作の割り込みによるプロセス終了となります.
シグナル自体はSIGINT (2)
が送信されます.
プロセスを一時的に中止するCtrl + z
はSIGTSTP (20)
が送信されます.
Appendix: ジョブのsuspendとfg
Linuxでは実行中のジョブをctrl + z
コマンドで, suspenedすることができます.
例えば, vim実行中にそのvimをsuspendしてみると,
1
2
3
4
% vim
# ctrl zをvim画面で入力
% % jobs
[1] + suspended vim
読み方として
[1]
は端末内部で稼働中のジョブに対する固有番号+
は1番目に新しいジョブ番号,-
の場合は2番目に新しいジョブ番号suspended
はジョブの状態vim
はジョブの内容
を指しています. このジョブを再開をする方法としてバックグラウンド実行とフォアグランド実行があります.
1
2
## fg commandとjob番号を指定
% fg %1
を端末に入力するとsuspendされていたjobをフォアグランド実行で再開することができます.
References
- UNIXの絵本, 株式会社アンク著
- kazmax Linuxで自宅サーバー > 実行中のプログラムをバックグラウンドにもっていく。フォアグラウンドにもってくる(bg、fg)
- Linux技術入門 > Linux - Process
(注意:GitHub Accountが必要となります)