『Linuxのしくみ』読んだ

#reading_log

ryoo14

Linuxのしくみ読んだので読書メモ。

基本的なことから各所で簡単にしか説明されていないことをの深掘りまで、中級者向けの良い本。

1章 Linuxの概要

プログラムとプロセス、カーネルとシステムコールなどについてや、静的ライブラリと共有ライブラリについて。

Go言語では共有ライブラリを一切使わないため、動作するバイナリはどの環境でも動作するらしい。

2章 プロセス管理(基礎編)

プロセスの生成(fork()とexecve())、プロセスの親子関係や状態など。実行状態、実行可能状態とかめちゃくちゃ久々に見た。

3章 プロセススケジューラ

プロセススケジューラによるプロセスの切り替わりやコンテキストスイッチについて。

4章 メモリ管理システム

メモリ管理について。ページキャッシュとバッファキャッシュを本当にさらっと触れる。

OOM killer様の話も。

仮想記憶について、ページテーブルは物理メモリ上のカーネルメモリに格納される。よく見かけるページフォールトは、プログラムが物理メモリと紐づいていない仮装アドレスにアクセスした際に発生するイベント。
また、ページテーブルはプロセス毎に生成され、階層型になっている。

ヒュージページの説明があったけど何が嬉しいのかちょっとよくわからなかった。

5章 プロセス管理(応用編)

プロセス管理の応用編。

fork()によるプロセス生成時、まずは親のページテーブルをコピーし、双方のテーブルの書き込みを禁止する。この時メモリのマッピング状況は親子間で同じであり、親子いずれかがデータを更新しようとした時に該当ページを別メモリにコピーし、テーブルを書き換え、書き込み権限を解放する。

プロセス通信のうち、共有メモリによって異なるプロセスから同じメモリを更新・読み取ることが可能。
シグナルの中には利用者が自由に用途を決めていいシグナルがあるが、こちらはシグナルの受信を検知する程度のことしかできない。
よく使うパイプもプロセス間通信のひとつ。

マルチプロセスとマルチスレッドの違いは、文字通り複数のプロセスを生成してメモリを共有する(コピーオンライト)などして処理を並列化するのがマルチプロセス、ひとつのプロセス中で複数の処理の流れを作るのがマルチスレッド。
ページテーブルのコピーが不要なため生成時間が短いが、ひとつのスレッドのエラーがプロセス全体に影響を及ぼすデメリットもあるのがマルチスレッド。

6章 デバイスアクセス

デバイスへのアクセスについて。

プロセスが物理デバイスにアクセスする際はカーネルがアクセスを代行する。

キャラクタデバイスとブロックデバイスの2つがある。前者はマウスやキーボードなど端末へのデータ入出力を行うのみ。後者はHDDやSSDなどのストレージデバイス。ブロックデバイスはファイルの読み書き以外にシーク操作が可能。

デバイスを操作する際の流れは、プロセス-デバイスファイル-デバイスドライバ-デバイス(レジスタ)。端末の仮想アドレスにデバイスへのアクセス状況をマップしながらデバイスのレジスタにアクセスしてデータのやりとりを行う。

デバイスの処理が終わるまで処理を止めると無駄なので、デバイスドライバは定期的にポーリングして処理の完了を監視する。ただこれは無駄が多いので、デバイスからCPUに完了を通知し、その通知を受けて発生させる割り込みという処理を発生させ、元のプロセスの処理を続行させる。

7章 ファイルシステム

デバイスの前に鎮座しているファイルシステムについて。

実際はプロセス-デバイスファイル-ファイルシステム-デバイスドライバ-デバイスの流れでストレージ装置にアクセスする。

ストレージを操作できるext4やxfsなどのファイルシステムに加え、メモリを扱うtmpfs、プロセスについての情報を得るためのprocfs、カーネルが保持する雑多な情報を扱うsysfsなど色々なファイルシステムがある。

8章 記憶階層

Linuxにおける記憶階層毎の説明。

端末の記憶装置はレジスタ-キャッシュメモリ-メモリ-ストレージデバイスの順にアクセス速度が遅くなる。メモリからキャッシュメモリに読み込まれたデータのうち、データ更新されたものはダーティであると表現し、キャッシュメモリからメモリに書き戻された際にダーティではなくなる。この書き込み方式にはライトスルーとライトバックの2つの方式があるが、メモリに書き戻さずに処理を継続する分、ライトバック方式のほうが高速。

CPUからメモリに対するキャッシュをキャッシュメモリが実現しているのと同様に、ストレージデバイスに対するキャッシュをページキャッシュと呼び、ストレージデバイス内のデータをメモリにキャッシュする。

また、ページキャッシュと似たような仕組みとしてバッファキャッシュがあり、こちらはファイルデータ以外のデータをキャッシュする仕組み。ファイルシステムにアクセスせずにストレージデバイスにアクセスする場合や、パーミッションなどメタデータにアクセスする際にキャッシュされる。

9章 ブロック層

ブロックデバイスの詳細について。HDDのセクタやプラッタについてや、スループット、レイテンシ、IOPSに関する説明など。

また、ブロック層のI/Oスケジューラ(I/Oリクエストを1つにまとめたり順番をセクタ番号順になるように並べ替える)や、readahead(アクセスされやすいデータ、セクタが連続しており次に読み出される可能性が高いデータを事前にページキャッシュに保存しておく)などの機能についても説明される。

10章 仮想化機能

言わずとしれた仮想化。KVMを扱ってた。

11章 コンテナ

namespaceを使って仮想化よりも軽量に閉じた環境を実現するコンテナ。

仮想化が仮想的なハードウェアやデバイスを経由し、あくまで別の端末として動作するため物理端末と比べてレイテンシが存在する一方、namespaceによって通常のプロセスを個別の空間に閉じ込めているだけなので余計な処理がない。

12章 cgroup

システムのリソースをプロセスにどの程度使わせるかを制御できる機能。

例えば利用可能なCPU時間を制限することで、負荷の高いプロセスが他プロセスの処理を遅延させるようなことがないように制御することができる。