kakts-log

programming について調べたことを整理していきます

「Linuxプログラミングインタフェース」を通読してみて

この記事は、Linux Advent Calendar 2024 第24日目の記事です。
Linux - Qiita Advent Calendar 2024 - Qiita

https://www.oreilly.co.jp/books/9784873115856/

OSまわりのインプットをしたいと思い、先日1年以上かけてLinuxプログラミングインタフェースという 約1600ページもある本を読み終わりました。

その中で、個人的に特に興味深く読めた項目について、かいつまんで取り上げます。

Linuxプログラミングインタフェース」で興味深かった項目について

第2章 基礎概念

OSのカーネルや、ファイルI/O、プロセス、シグナル、スレッドなど、基本的な機能についての概略がまとめられています。

第3章 システムプログラミング

システムコールについて、そしてシステムコールを扱って実装されているライブラリ関数や標準のCライブラリであるglibcなどについての説明があります。

アプリケーションがCのラッパー関数経由でシステムコールを実行するにあたり、 そのラッパー関数がシステムコールを呼び出し、それによりユーザモードからカーネルモードへ移行し、指定したシステムコールに対応する処理を実行する流れについての説明が詳しく書かれています。

第4〜5章 ファイルI/O

ファイル操作の基本となるファイルI/Oについての説明があり open(), read() write()などのシステムコールを使ってファイルの読み書き、クローズの基本的な操作について説明されています。

また、ファイル操作において重要なファイルディスクリプタについても丁寧二節笑みしてあったり、ファイルに対するフラグやファイルディスクリプタの複製、ノンブロッキングI/Oについての説明もとても面白く読めました。

第6章 プロセス

Linuxにおけるプロセスについての説明や、プロセスID、メモリレイアウトや、メモリ管理において重要なスタック・スタックフレームも扱っています。

第7章 メモリ割り当て

malloc()、free()など、ヒープ上のメモリ割り当て、解放についてサンプルコードを動かしつつ理解ができました。

第13章 I/Oのバッファリング

システムコールや、stdioなどの標準ライブラリ関数におけるデータのバッファリングについての説明がありました。 ユーザプロセスとカーネルのやりとりににおける速度や効率を改善するために、データを毎回やり取りせず、メモリ上でバッファして、指定したサイズごとにデータをやり取りするという考え方と、それに伴うstdio関数での注意点についてが非常に勉強になりました。

また、バッファサイズによるI/O性能の影響についても興味深かったです。

第20〜22章 シグナルについて

カーネル->プロセス、あるプロセスから別のプロセスにおけるシグナル送信と、その送信方法について詳しく説明されています。 また、プロセスが特定のシグナルを受け取った際に行う処理を定義するシグナルハンドラや、シグナルをブロックするシグナルマスクについても概要を理解することができました。

第24〜28章 プロセスについて

プロセスの作成、終了の基本的な操作や、親プロセスが作成した子プロセスに対する監視と、ゾンビプロセスについて、プロセスに関する基礎知識がまとまっています。

また、プロセス作成において利用できるfork()とexecve()の違いについてコードを書きながら理解することができました。

第29章〜33章 スレッドについて

Pthreads APIを利用したスレッドの作成や終了、そしてスレッドとプロセスの違いなどスレッドの基礎知識についての説明がありました。 また、mutexを使った同期や、スレッドセーフ(リエントラント)についての考え方、注意点が大変勉強になりました。

第37章 デーモン

以前の章で説明したプロセスの作成方法などを踏まえて、バックグラウンドで動作し、特定の制御端末を持たないデーモンについての詳細な説明と、デーモンプロセスの作り方について学ぶことができました。

第56〜61章 ソケット

同一ホストやネットワークを介した異なるホスト間で通信するためのソケットについて基本的な概要から、UNIXドメインソケットやTCP/IPの基礎、インターネットドメインについてもかなり詳しくまとめられていました。 特にwebサービスなどを開発するエンジニアにとっては繰り返し読んで理解しておきたい項目でした。 また、socket()によるソケット作成、bind()によるソケットアドレスのバインドやlistenを行い、サーバとクライアントを実装して手を動かしてソケット通信を理解できました。

書籍内のコードのハンズオンについて

システムコールを扱っている項目では、そのシステムコールを使ったサンプルコードが提示されており、実際にコードを書いて手を動かして確認できるようになっています。
ただ、Linuxの環境がなかったため、ローカルPCでubuntuのDockerコンテナを立ち上げ、そのコンテナ内でプログラムを実行する方法で進めました。

この本の公式のサイトでソースコードがまとめられているのですが、実際にビルドして実行する環境までは整っていなかったため、github上でこの本のコードをあげている方のリポジトリを参考にしながら、ソースコードのビルドしてプログラムの実行もできる環境を整えました。 man7.org

下記のリポジトリにまとめているので、もしコードを書きながら読み進めたい方は参考にしてみてください。
github.com

Linuxプログラミングインタフェース」を読んでみてどうだったか

長期間少しずつ読み進めるなかで、Linuxの各機能についての歴史的な経緯の説明があったり、ファイル操作、プロセス、スレッド、ソケットなどを扱うためのシステムコールの利用例をコードを書きながら学ぶことができ、Linuxを扱う上での基礎を身につけることができ、とても学びの多い本でした。

1600ページもあるため、全部の項目についての知識定着はできていないですが、重要な項目にきついてはコードを書き、Dockerコンテナ上で動作確認を進めることができ理解を深めることができました。

OS周りの知識が一通り取り上げられているので、今後業務や個人で扱う際に、各機能について頭の中でインデックスを構築することができ、通読できてよかったと思っております。 量は多いですが、1回通読して終わるのは勿体無いくらい、体型的に知識がまとまっていて、個人的にソケットやファイル操作、プロセス、スレッドなどの章はたびたび繰り返し読み返して知識を定着させたいと思いました。

各章は意外と丁寧に優しく書いてあるので、ある程度詳しい方だけでなくLinux周りの経験が浅い人にもおすすめしたいです。