ryo’s blog

日々学んだことをまとめています.

第10章 システム・レベルI/O

10章について
この章では、ファイルやディレクトリプタといったUNIX I/Oの基本的なコンセプトについて説明されていました。
Webサーバの実装や並行プログラミングにつながる章となっています。
以下まとめです。


ファイルあれこれ

オープン

ファイルをオープンするとそのファイルを特定するディスクリプタを返す。
カーネルはオープンしたファイルのすべての情報を追跡するが、アプリケーションはディスクリプタを追跡するだけ。


クローズ

カーネルはオープン時に作成したデータ構造を解放し、ディスクリプタを戻す。
プロセスが何らかの理由で終了したとき、カーネルはオープン中のすべてのファイルをクローズする。


読み書き

ファイルサイズ以上の読み込み操作を行うと、ファイル終端(EOF)とよばれる状態になり、アプリケーションに検出される

読み込み : ファイルからメモリにコピーする。
書き込み : メモリからファイルにコピーする。


ファイルタイプ

ディレクトリ、ソケット、名前付きパイプなどがある。


ショート・カウント

状況によって要求より少ないバイト数しか転送しないことがある。

(例) 30バイトのファイルに対し、50バイト読み込もうとした場合。
read はショート・カウント 20 を返す。
その後にショート・カウント 0 を返すことでEOFを知らせる。


ファイルのメタデータの読み込み

stat や fstat 関数を呼び出すことでファイルについての情報(メタデータ)を取り出せる。


ディレクトリの読み込み

opendir, readdir, closedir 関数でディレクトリの情報を扱うことができる。


カーネルのファイル管理

カーネルはオープンしたファイルを 3つの関連するデータ構造を用いて表現している。


ディスクリプタ・テーブル(プロセスごとに一つ)

ファイル・ディスクリプタによってエントリに索引がつけられている個別のディスクリプタ・テーブルを持っている。


ファイル・テーブル (すべてのプロセスで共有)

各エントリは、ファイルポジションや、参照カウント、v-ノード・テーブルなどを持っている。
ディスクリプタをクローズすると、参照カウントを減少させ、0 になるとファイル・テーブルのエントリを削除する。


v-ノード・テーブル (すべてのプロセスで共有)

stat 構造体のほとんどの情報が格納されている。


ファイルの共有

同じファイルに対して 2回 open 関数を呼び出すことで、ファイル共有ができる。


ファイルの継承

forkした場合、親プロセスと子プロセスが同じオープン・ファイル・テーブルとファイル・ポジションを共有する。
ファイル・テーブルのエントリを削除するには、親と子で両方ともクローズする必要がある。


標準I/O

標準I/Oライブラリはオープンしたファイルをストリームとして、モデル化している。
すべての ANCI C プログラムはオープン中の 3つのストリーム stdin, stdout, stderr を持った状態で実行を開始する。


ソケット

Linux のネットワーク抽象化は、ソケット とよばれるファイル・タイプがある。
ソケット・ディスクリプタを読み書きすることで他のコンピュータ上で動作しているプロセスと通信する。


感想

次章以降につながる事前知識のような感じだったので、スムーズに読みすすめられました。
実際にはRIOパッケージを用いた安全な読み書きについても書かれていました。
コードサンプルが多かったので理解しやすかったです。