【Linux カーネル: OS 基礎入門2】CPU・プロセス管理

本記事は Linux カーネル解説の第2回「プロセス管理・CPU 割り当て」に関する記事です。

なお、本記事は以下の書籍を参考にしています。

その他の Linux カーネルの解説については以下の記事をご覧ください。

スポンサーリンク

プロセスとは

プロセスとは、CPU で実行するためにメモリにロードしたプログラムのことです。

メモリについて詳細を知りたい方は以下の記事をご覧ください。

プロセスの確認コマンド

ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  43920  5732 ?        Ss    2021   4:40 /usr/lib/systemd/systemd --switched-root --system --deserializ
root         2  0.0  0.0      0     0 ?        S     2021   0:00 [kthreadd]
ヘッダ説明
USERユーザー名
PIDプロセス ID
%CPUプロセスの使用率
%MEM物理メモリに対するプロセスの割合
VSZ仮想メモリに割り当てたプロセスのサイズ
RSS物理メモリに割り当てたプロセスのサイズ
TTY制御端末
STATプロセスの状態
・D 割り込み不可能なスリープ状態 (通常 IO 中)
・R 実行中または実行可能状態 (実行キューにある)
・S 割り込み可能なスリープ状態 (イベントの完了を待っている)
・T ジョブ制御シグナルまたはトレースされているために停止中の状態
・W ページング状態 (2.6.xx カーネルからは無効)
・X 死んだ状態 (見えるべきではない)
・Z 消滅した (ゾンビ) プロセス
STARTプロセスの起動日
TIME累積した CPU 時間
COMMANDプロセスの実行コマンド

メモリ上のプロセスの構造

プロセスはメモリ上のアドレス空間に、次のセグメント (分類) ごとに配置します。

5つの各セグメントには、次のようなデータが配置されます。

  • テキスト・セグメント: CPU が実行する機械語命令
  • データ・セグメント: 初期化済みの static 変数 or グローバル変数
  • bss・セグメント: 初期化していない static 変数 or グローバル変数
  • ヒープ・セグメント: プロセス実行時に動的に確保される領域 (malloc 等)
  • スタック・セグメント: スコープが終了すると消えるデータ (ローカル変数、関数パラメータ、メソッド等)

プロセスとスレッドの違い

1つのプロセスは、1つ以上のスレッドを持ちます。

プロセスとスレッドの違いは以下のとおりです。

プロセススレッド
説明プログラムの実行単位CPU の利用単位
メモリ子プロセス用に新規領域を確保親スレッドと子スレッド間で共有する
(スタック・セグメント以外)
生成遅い
(メモリに新規領域を確保するため)
速い

例えば、お絵かきプログラムがあったとします。

  • プロセス:お絵かきプログラムを実行したもの
  • スレッド:実行したお絵かきプログラムの各 CPU の処理(「マウス操作の受付」・「絵の描写」等)

プロセス (スレッド) の並列処理

プロセスを CPU で処理する場合、並列に処理する方法は以下の4つが存在します。

  • マルチ CPU : 複数の CPU を利用します。
  • マルチコア : 1つの CPU にある複数のコアを利用します。
  • ハイパースレッディング : 1つのコアに複数のスレッドを割り当てます。
  • マルチスレッド:1つのプロセスが複数のスレッドを持ちます。

CPU 確認コマンド

利用している CPU は、lscpu (もしくは cat /proc/cpuinfo) コマンドで確認可能です。

lscpu
CPU:                                 2 //論理 CPU の(スレッドの割り当て可能な)数です
オンラインになっている CPU のリスト: 0,1
コアあたりのスレッド数:              2 //ハイパースレッディングによる見せかけのコア数です
ソケットあたりのコア数:              1 //1CPUに含まれるコア数です
ソケット数:                          1 //物理 CPU (実際の CPU)の数です
スポンサーリンク

プロセス管理とは

プロセス管理とは、いつ、どのプロセスにどれぐらいの時間 CPU を割り当てるかを管理することです。

1つのプロセスが CPU を独占してしまうと他の処理ができなくなります。

そこで、一定時間が経過すると CPU で処理するプロセスを切り替えることで、1つのプロセスによる CPU の独占を防ぎ、複数のプロセスを並行して実行可能となります。

例えば、1つの CPU で「インターネットを閲覧するプロセス」と「メールを送信するプロセス」を並行して実行可能となります。

プロセス管理では、CPU の割り当てを管理するために以下の3つの仕組みを利用します。

プロセスの状態遷移

プロセスのライフサイクル (プログラムが開始してから終了するまで) には、以下の5つのステートが存在します。

  • 開始:初期化するためのステート。「実行可能」ステートに移行
  • 実行可能CPU の割り当てを待つためのステート。「実行中」のプロセスが他のプロセスに割り込まれて中断した場合にもこのステートとなります
  • 実行中:プロセスに CPU を割り当てた(ディスパッチした)ステート
  • 待機:デバイスの I/O (SSD 等のデータ読み書きの処理)待ちで CPU の処理が必要ない場合のステート。I/O 処理が終わると「実行可能」ステートに移行します
  • 終了:プロセスの処理が完了・中止した場合はこのステートとなります

PCB (Process Control Block)

ステートを含むプロセスに関する情報は、メモリカーネルスタックに以下の PCB 置くことで管理します。

各項目の意味は以下のとおりです。他にも色々あります。

  • Process ID: プロセスを一意に識別する番号です。(PID)
  • State: プロセスの状態遷移で、現在どのステートになのかを表します
  • Pointer: 親プロセスのポインタ
  • Priority: プロセスの優先度
  • Program Counter: 次に実行する命令のポインタ
  • CPU registers: 実行中ステートのプロセスのレジスタの値(?)
  • I/O Information: プロセスに割り当てられた I/O デバイスのリスト
  • Accounting information:プロセスの実行に使用されるCPUの量、時間制限、実行ID

CPU スケジューラー (短期スケジューラー)

CPU スケジューラーは、「実行可能」ステートのプロセスから、次に CPU を割り当てるプロセスを決定します。

CPU スケジューラーが次に CPU を割り当てるプロセスを決定すると、割り込みによりディスパッチャが「プリエンプション」と「ディスパッチ」を行うことでプロセスを切り替えます。

  • プリエンプション: 実行中のプロセスのステートを「実行中」から「実行可能」に変更
  • ディスパッチ:待機中のプロセスのステートを「実行可能」から「実行中」に変更

ディスパッチャにより処理を中断したプロセスは、PCB へ再開地点を表すプログラムカウンタやレジスタの値を保存します。この中断処理や再開処理をコンテキストスイッチと言います。

プロセススケジューラーが CPU の割り当てを決定する際に利用するスケジューリングアルゴリズムには、主に以下の4つが存在します。

  • First Come First Serve (FCFS)
  • Shortest Job Next (SJN)
  • Priority Based Scheduling
  • Round Robin Scheduling

First Come First Serve (FCFS)

FCFS は以下の特徴を持ちます。

  • 先着順でプロセスを実行
  • FIFO(First In First Out) キューにて実装
  • non-preemptive(割り込み不可能)
  • 平均待ち時間が長い
https://www.tutorialspoint.com/operating_system/os_process_scheduling_algorithms.htm

平均待ち時間: (0+4+6+13) / 4 = 5.75

Shortest Job Next (SJN)

SJN は以下の特徴を持ちます。

  • 処理時間が短いプロセスから CPU を割り当てます
  • 平均待ち時間を最小に抑えるためのアルゴリズム
  • non-preemptive(割り込み不可能)
  • CPU 処理時間を事前に知っている(もしくは計算する)必要があります
ProcessArrival TimeExecution TimeService Time
P0050
P1135
P22814
P3368

平均待ち時間: (0 + 4 + 12 + 5)/4 = 21 / 4 = 5.25

Priority Based Scheduling

Priority Based Scheduling は以下の特徴を持ちます。

  • 優先度の高いプロセスから実行されます
  • 同じ優先度のプロセスは先着順です
  • 優先度は、メモリ要件、時間要件等に基づいて決定します

なお、プロセスの優先度は以下のコマンドの結果の PRI 列で確認可能です。(低いほうが優先度が高い)

ps alx
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
1     0     2     0  20   0      0     0 -      S    ?          0:01 [kthreadd]
1     0     4     2   0 -20      0     0 -      I<   ?          0:00 [kworker/0:0H]

PRI は NI(nice 値)を元に決定するため、nice コマンドにてプロセスの優先度を変更可能です。

ProcessArrival TimeExecution TimePriorityService Time
P00510
P113211
P228114
P33635

平均待ち時間: (0 + 10 + 12 + 2)/4 = 24 / 4 = 6

Round Robin Scheduling

Round Robin Scheduling は以下の特徴を持ちます。

  • 各プロセスはクオンタム(CPU を割り当てる固定時間)を持つ
  • preemptive(割り込みが発生する)ため、プロセスが並行して動作可能
  • クオンタムの期間が終了すると、割り込みが発生し次のプロセスに処理が移る

クオンタムが3だとすると、3経過ごとにプロセスが切り替わる。

平均待ち時間: (9+2+12+11) / 4 = 8.5

スポンサーリンク

最後に

Linux カーネル「プロセス管理・CPU割り当て」に関する説明は以上となります。

その他の Linux カーネルの機能について知りたい場合は以下の記事をどうぞ。

本記事は以下のサイトを参考にしました。

Operating System - Processes
Operating System - Processes, A process is basically a program in execution. The execution of a process must progress in a sequential fashion.