Linux: マルチタスクとプロセス制御

ps command 1/N

公開日: 2023-08-10
更新日: 2023-09-28

  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 + zSIGTSTP (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



Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)