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

CPUCPUとは、コンピュータの構成要素の1つで、データを処理するための機械です。
プロセスプロセスとは、CPU で処理するために、メモリにロードしたプログラムのことです。
Linux カーネルの機能
スポンサーリンク

プロセスとは

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

プロセスの構造

プロセスは、以下のようにセグメント (分類) に分けて、メモリ上に配置します。

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

プロセス管理とは

プロセス管理とはプロセス管理とは、「いつ・どのプロセスに・どのくらいの時間」プロセスに CPU を割り当てるか決定することです。

プロセス管理は、1つのプロセスが CPU を独占して、他のプロセスが動かなくなる事を防ぎます

プロセス管理では、以下の3つの仕組みを利用します。

プロセスの状態遷移

プロセスの状態遷移では、以下の5つの状態を遷移します。
状態説明
開始初期化するための状態
実行可能CPU の割り当て待ちの状態
実行中プロセスに CPU を割り当て中の状態
他のプロセスに割り込まれて中断すると、「実行可能」状態に移行
待機デバイスの I/O (SSD 等のデータ読み書き)待ちの状態
I/O 処理が終わると「実行可能」状態に移行
終了プロセスの処理が完了・中止した状態
処理説明プロセスの状態
ディスパッチプロセスに CPU の割り当て (実行)「実行可能」から「実行中」に変更
プリエンプションプロセスに CPU を剥奪 (一時中断)「実行中」から「実行可能」に変更

一時中断したプロセスを再開するには、「前回どこまで処理したか」という情報が必要です。

この情報は PCB と呼ばれるブロックに保存します。

PCB (Process Control Block)

PCB (Process Control Block)とは、プロセスの状態などを記録したブロックです。

PCB はプロセスの再開時に利用されます。

PCB の内容は以下のとおりです。

メモリカーネルスタック上で管理
項目説明
Process IDプロセスを一意に識別する番号 (PID)
State現在のプロセスの状態
Pointer親プロセスのポインタ
Priorityプロセスの優先度
Program次に実行する命令のポインタ
CPU registers「実行中」状態のプロセスのレジスタの値(?)
I/O Informationプロセスに割り当てられた I/O デバイスのリスト
Accounting informationプロセスの実行に使用されるCPUの量、時間制限、実行ID

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

CPU スケジューラーとは、「実行可能」状態のプロセスの中から、次に CPU を割り当てるプロセスを決定する機能です。

CPU スケジューラーが、ディスパッチ・プリエンプションするプロセスは、スケジューリングアルゴリズムによって決定します。

スケジューリングアルゴリズム

スケジューリングアルゴリズムには、主に以下の4つが存在します。

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

First Come First Serve (FCFS)

First Come First Serve (FCFS) とは、先着順でプロセスを実行するアルゴリズムです。

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

  • FIFO(First In First Out) キューにて実装
  • non-preemptive(割り込み不可能)
  • 平均待ち時間が長い
https://www.tutorialspoint.com/operating_system/os_process_scheduling_algorithms.htm
ProcessWait Time : Service Time - Arrival Time
P00 - 0 = 0
P15 - 1 = 4
P28 - 2 = 6
P316 - 3 = 13

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

Shortest Job Next (SJN)

Shortest Job Next (SJN) とは、処理時間が短いプロセスから CPU を割り当てるアルゴリズムです。

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

  • 平均待ち時間を最小に抑えるためのアルゴリズム
  • non-preemptive(割り込み不可能)
  • CPU 処理時間を事前に知っている(もしくは計算する)必要があります
https://www.tutorialspoint.com/operating_system/os_process_scheduling_algorithms.htm
ProcessWait Time : Service Time - Arrival Time
P00 - 0 = 0
P15 - 1 = 4
P214 - 2 = 12
P38 - 3 = 5

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

Priority Based Scheduling

Priority Based Scheduling とは、優先度の高いプロセスから実行するアルゴリズムです。

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

  • 同じ優先度のプロセスは先着順です
  • 優先度は、メモリ要件、時間要件等に基づいて決定します
https://www.tutorialspoint.com/operating_system/os_process_scheduling_algorithms.htm
ProcessWait Time : Service Time - Arrival Time
P00 - 0 = 0
P111 - 1 = 10
P214 - 2 = 12
P35 - 3 = 2

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

なお、プロセスの優先度は以下のコマンドの結果の 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 コマンドにてプロセスの優先度を変更可能です。

Round Robin Scheduling

Round Robin Scheduling とは、クオンタム(CPU を割り当てる固定時間)ごとに実行するプロセスを切り替えるアルゴリズムです。

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

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

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

ProcessWait Time : Service Time - Arrival Time
P0(0 - 0) + (12 - 3) = 9
P1(3 - 1) = 2
P2(6 - 2) + (14 - 9) + (20 - 17) = 12
P3(9 - 3) + (17 - 12) = 11

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

プロセスの確認コマンド

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 消滅した (ゾンビ) プロセス
・I Idle 状態
STARTプロセスの起動日
TIME累積した CPU 時間
COMMANDプロセスの実行コマンド
スポンサーリンク

スレッドとは

スレッドスレッドとは、プロセスの CPU (のコア) の割り当て単位です。
1つのプロセスが複数のスレッドを持つこともある

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

プロセスとスレッドの違い「プロセスはプログラム単位」、「スレッドは CPU の利用単位」です。

以下に MySQL プロセスと、MySQL プロセスが持つスレッドの関係を示します。

1つの MySQL プロセスが複数の MySQL スレッドを持つ例

プロセスとスレッドの違いを表にまとめると以下のとおりです。

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

スレッドの確認コマンド

ps aux -L
USER       PID   LWP %CPU NLWP %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
(中略)
mysql    29942 29942  0.0   28  2.2 1382864 181528 ?      Sl   09:45   0:00 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
mysql    29942 29943  0.0   28  2.2 1382864 181528 ?      Sl   09:45   0:00 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
mysql    29942 29944  0.0   28  2.2 1382864 181528 ?      Sl   09:45   0:00 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
(中略)
ヘッダ説明
USERユーザー名
PIDプロセス ID
LWP軽量プロセス (Light Weight Process) またはスレッドの ID
%CPUプロセスの使用率
NLWPLWP (スレッド) の数
%MEM物理メモリに対するプロセスの割合
VSZ仮想メモリに割り当てたプロセスのサイズ (メモリ管理の記事で説明)
RSS物理メモリに割り当てたプロセスのサイズ (メモリ管理の記事で説明)
TTY制御端末
STATプロセスの状態
・D 割り込み不可能なスリープ状態 (通常 IO 中)
・R 実行中または実行可能状態 (実行キューにある)
・S 割り込み可能なスリープ状態 (イベントの完了を待っている)
・T ジョブ制御シグナルまたはトレースされているために停止中の状態
・W ページング状態 (2.6.xx カーネルからは無効)
・X 死んだ状態 (見えるべきではない)
・Z 消滅した (ゾンビ) プロセス
・I Idle 状態
STARTプロセスの起動日
TIME累積した CPU 時間
COMMANDプロセスの実行コマンド
スポンサーリンク

CPU とは

CPUCPUとは、コンピュータの構成要素の1つで、データを処理するための機械です。

CPU の処理の種類

CPU で並列処理するには、以下の方法が存在します。

マルチ CPU

マルチ 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)の数

関連情報

Linux カーネルの機能

参考サイト

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

Operating System - Processes
Operating System Processes - This tutorial covers concepts like overview of Operating System, Types, Services, Properties, Process Scheduling, CPU Scheduling al...