試して理解 Linuxのしくみの第2章を読んだ

blog.ryskit.com

の続き。

第2章では、CPUはユーザモードとカーネルモードを切り替えて処理を実行しているということを学んだ。

CPUのモード遷移の図や実験で試したプログラムのCPUのモードの遷移図は分かりやすい。

試したコマンドは、strace, sar

簡単なプログラムを書いて、「ユーザモードで動く場合」「カーネルモードで動く場合」のプロセスのモードの割合を確認した。

まだ難しくない内容なので、どんどん進めていこう。

ノート

第2章 ユーザモードで実現する機能

  • 各種プロセスは、プロセス生成、ハードウェアの操作など、カーネルの助けが必要なときにはシステムコールという手段によってカーネルに処理を依頼する
  • システムコール
    • プロセス生成、削除
    • メモリ確保、解放
    • プロセス間通信
    • ネットワーク
    • ファイルシステム
    • ファイル操作(デバイスアクセス)
  • システムコールを発行すると、CPUにおいて割込みというイベントが発生する
    • これにより、CPUではユーザモードからカーネルモードに依頼し、内容に応じてカーネルの処理が動く
    • 処理が終われば、ユーザモードに戻りプロセスの動作を継続する
  • straceの出力は、1つのシステムコール発行が1行に対応している
  • sarコマンドでプロセスがユーザモードとカーネルモードのどちらで実行しているかの割合を取得できる
  • sar -P ALL 1
  • allになっている行は全CPUの平均値
  • ユーザモードでプロセスを実行している割合は、%userと%niceの合計
  • CPUコアが、カーネルモードでシステムコールなどの処理を実行している時間の割合は、「%system」によって得られる
  • %idleはCPUコア上でプロセスもカーネルも動いていない状態
各行が1つのCPUに対応している
サーバーは1CPUなので、一つ

Average:        CPU     %user     %nice   %system   %iowait    %steal     %idle
Average:        all      0.00      0.00      0.00      0.00      0.00    100.00
Average:          0      0.00      0.00      0.00      0.00      0.00    100.00
loop処理実行後

Linux 4.15.0-50-generic (133-130-123-136)   06/10/19    _x86_64_    (1 CPU)

21:51:46        CPU     %user     %nice   %system   %iowait    %steal     %idle
21:51:47        all    100.00      0.00      0.00      0.00      0.00      0.00
21:51:47          0    100.00      0.00      0.00      0.00      0.00      0.00

Average:        CPU     %user     %nice   %system   %iowait    %steal     %idle
Average:        all    100.00      0.00      0.00      0.00      0.00      0.00
Average:          0    100.00      0.00      0.00      0.00      0.00      0.00
親プロセスのプロセスIDを得るシステムコールのループ処理実行後

sar -P ALL 1 1
Linux 4.15.0-50-generic (133-130-123-136)   06/10/19    _x86_64_    (1 CPU)

21:55:02        CPU     %user     %nice   %system   %iowait    %steal     %idle
21:55:03        all     46.46      0.00     53.54      0.00      0.00      0.00
21:55:03          0     46.46      0.00     53.54      0.00      0.00      0.00

Average:        CPU     %user     %nice   %system   %iowait    %steal     %idle
Average:        all     46.46      0.00     53.54      0.00      0.00      0.00
Average:          0     46.46      0.00     53.54      0.00      0.00      0.00
  • %systemが数十のような大きな値に似合っている場合は、むやみにシステムコールを発行しているか、システム負荷が高すぎる場合が多い
  • straceに「-T」オプションをつけると、各種システムコールの処理にかかった時間をマイクロ秒の精度で採取できる
  • システムコールは、通常の関数呼び出しとは違い、直接呼び出せない
    • アーキテクチャ依存のアセンブリコードを使って呼び出す必要がある
    • この問題を解決するために、OSは内部的にシステムコールを呼び出すだけの、システムコールラッパーと呼ばれる一連の関数を提供している
    • https://twitter.com/_ryskit/status/1138069450014330881
  • glibcは、システムコールのラッパー関数を含む
    • ldd /bin/echo
    • ldd ppidloop
    • ldd /usr/bin/python3