Linuxをちゃんとざっくり理解していく
[到達したい状態]
- Linuxがプログラムの実行に対してどのような関係性なのかを理解する
- 概念的理解も大事だけど、なるべくコードを通して理解する
[やること]
- ふつうのLinuxプログラミングを読む
- 実際にコードを書いて、理解する
Linuxの世界を構成する3要素
- ファイルシステム
- プロセス
- ストリーム
Linuxという言葉は狭義と広義で意味が異なる。
狭義のLinuxとは、Linuxカーネルのこと。カーネルは上で説明したLinuxの世界を構成する3要素を作り出しているプログラムである。カーネルはOSの核である。カーネルはコンピュータを構成する全てのハードウェアとソフトウェアを管理している。
広義のLinuxとは、ディストリビューションのこと
そういや以前OSはハードウェアの基本動作をを定義したり、管理しているってのを学んだ。
もっと厳密に言い換えるとOSの中にカーネルが存在していて、そのカーネルがハードウェアを管理しているのか。
デバイスとデバイスドライバについて
デバイスとは、PCを構成する比較的単位の大きな物理的な「部品」のこと。要はハードウェアである。
現実にはいろんな種類のハードウェアがあり、そのハードウェアに適するようにOSを書き換えるのは現実的ではない(OSとハードウェアが直接的に依存している。 OSが特定のハードウェアの内部構造を知りすぎているので、ハードウェアのある部分を変更した良いだけなのにOSも変更しないといけなくなる。このように依存していると1個変更したいのに2個変更する必要性がある)。
どんなデバイスでも、デバイスを操作する以外のコードは共通なので、デバイスを操作する部分だけ独立させて交換可能にした方が便利。そこでデバイスドライバを使う。
デバイスドライバとは、特定のデバイスを操作するためのソフトウェアである。省略してドライバとも言う。
システムコール
ハードウェアを操作したければカーネルに命令するしかない。カーネルはデバイスドライバを経由してデバイスを操作する。カーネルに命令したいなら、システムコールを実行すれば良い。
システムコールとは、カーネル(システム)が提供する機能をアプリケーション側から呼び出すための(call)仕組みである。
システムコールという仕組みによって、アプリケーションに対してハードウェアを操作するためのインターフェースが提供される。インターフェースが提供されるので利用者は細かい実装を知ることなく特定のハードウェアの機能が利用できる。
ライブラリ関数
ライブラリ関数とは、ライブラリに定義されていて、ライブラリが提供する関数。
ライブラリは図書館で、ライブラリ関数が本のイメージ。
実際のプログラムでライブラリ関数を呼び出すためにはリンク作業が必要。
API
API(Application Programming Interface)とは、あるプログラムから別のプログラムのある機能を呼び出すためのインターフェースのことである。
APIの例
- ライブラリのAPIは、関数である。この関数がインターフェースとして提供されているおかげで、ライブラリのある機能を呼び出すことができる。
- アプリケーション側からカーネルに定義されている機能を呼び出す際、カーネルのAPIはシステムコールである。
- LinuxコマンドもシェルからLinuxのある機能を呼び出しているのでAPIである。
ファイル
Linuxにおけるファイルとは、3つの意味がある
- 広義のファイル
- Linuxにおける広義のファイルとは、テキストファイル、バイナリファイル、ディレクトリ、シンボリックリンクなどを指す言葉である。ファイルという言葉がこの意味で使われている時、ファイルという言葉は広義の意味で使われている
- 広義のファイルにおけるディレクトリとは、他のファイル(広義のファイル)を複数入れることができるファイルである。
- 広義のファイルにおけるシンボリックリンクとは、他のファイルの名前を格納したファイルである。
- 広義のファイルにおけるデバイスファイルとは、デバイス(ハードウェア)をファイルとして表現したものである。
- 広義におけるファイルは、何らかのデータを保持している。
- 広義におけるファイルは、パーミッションを持つ。
- 狭義のファイル
- Linuxにおける狭義のファイルとは、内容がそのまま記録されている普通のファイルである。
- ストリーム
-
ストリームとは、バイト列が流れる通り道のこと。
- バイト列とは、バイトデータの集合のこと
- 例えばあるプロセスがファイルの内容にアクセスしたい時、システムコールを利用してカーネルにプロセスとファイルを繋ぐようなストリームを作ってもらう。その後、システムコールを使ってストリームを操作して、ファイルの中身を取り出せば良い。
- プログラミングの世界では、ストリームからバイト列を取り出すことを読む(read)と呼ぶ。逆にバイト列を流し込むことを書く(write)と呼ぶ。「ストリームからバイト列を読む」「ストリームからバイト列に書く」「ファイルの内容を読む」「ファイルに書く」のように使う。
- プロセスをストリームを経由してデバイスと繋げることができる。キーボードもキーを表すバイト列をストリームを経由してプロセスに送りつけていると考えることができる。このようなデバイスとプロセスのストリームを得るためのとっかかりとして、デバイスファイルが存在している。
- ストリームは、システムコールのread()とwrite()で操作できて、ファイルディスクリプタで識別できる。
-
ストリームとは、バイト列が流れる通り道のこと。
Linuxの広義のファイルにおけるUNIXドメインソケットってプロセス間通信で使うファイルなのか。現在ではTCPソケットで代替できるそう。
ストリームって概念めちゃくちゃ大事やな。
ストリームがあるから
- あるプロセスから、あるプロセスが生成したバイト列を取得できる
- あるプロセスから、あるファイルのデータをバイト列として取得できる
- あるプロセスから、あるデバイスによって作られたバイト列を取得できる
やっぱ調べてみると、ストリーム内にはバッファが存在するくさい。
バッファとは、データを一時的に保存しておく場所。ストリーム内のバッファを経由して、あるプロセスからあるプロセスやファイルにバイト列を流し込んでいる。
stdioライブラリ(標準入力ライブラリ)を使うと、読み書きするインターフェースを提供してくれたり、独自バッファを用意して効率化してくれる
ファイルシステム
- ファイルシステムとは、ファイルという概念を成立させているシステム。
- ファイルシステムはハードディスクなど物理的な装置の上に存在する
- ファイルシステムという仕組みがあるから、データに名前をつけて保存することができる。
プロセスとプログラムの違い
- プロセスとは、ざっくりいうとメモリ上で実行中のプログラムのことである。
- プロセスは、全プロセスに対して重複しないようなユニークなid(プロセスid)を持っている
- それに対してプログラムという言葉は、ファイルの形態で存在しているデータも含む
- 一つのプログラムがあれば、プロセスはいくつでも作れる。
パイプ
パイプとは、あるプロセスとあるプロセスを繋ぐためのストリームのこと。
ストリームを利用してネットワーク通信を説明する
ネットワーク通信とは、あるコンピュータからあるコンピュータを繋ぐためのストリームである。
ネットワーク通信におけるストリームは、あるコンピュータのプロセスから別のコンピュータのファイルに繋げたり、あるコンピュータのプロセスから別のコンピュータのプロセスに繋げたりできる。
プロセス間通信
プロセス間通信とは、パイプやネットワーク通信のように、プロセス同士がストリームを通じてデータをやりとりしたり、意思の疎通をすること。
端末とは
- 端末とは、ユーザがデータをコンピュータに入出力するためのハードウェアのこと。
- UNIXでは端末のことをttyと呼ぶ。
- ttyはテレタイプ(TeleTYpe)の略。
- テレタイプとは、UNIX黎明期に使われていた端末のこと。
シェル
シェルとは、ユーザーからの命令を解釈して実行するプログラムのこと
- シェルのコマンドラインに実行ファイルの名前を入力してエンターを押すと、命令が実行される。シェルは最終的に実行する。だから命令が実行されたのか。
- シェル自体はストリームからコマンドを読み込んで実行するプログラム。
ファイルディスクリプタ
- プロセスからストリームを扱うには、ファイルディスクリプタが必要。
- ファイルディスクリプタとは、プログラム上からストリームを識別するための番号。
- カーネルがストリームとファイルディスクリプタを内部で紐づけて管理している。プログラム側ではファイルディスクリプタを指定すれば、ストリームを利用できる
シェルからプロセスを起動する場合、どのプロセスも3つのストリームを初めから持っている。
以下の3つのストリームである。
- 標準入力
- 標準出力
- 標準エラー出力
これらのストリームはそれぞれファイルディスクリプタの0、1、2に対応している。
標準入力や標準出力の標準とは「デフォルトの』という意味。
catコマンドを単体で使った場合、catプロセスは標準入力で端末(キーボードからの入力)とつながり、catプロセスは標準出力でディスプレイとつながる。
catコマンドにファイルを指定した場合、catプロセスは標準入力でファイルとつながる。出力は一緒。
catプロセスは自分がファイルから読み込んでいようがキーボードから読み込んでいようが知らない。
とりあえず知りたいことは理解できたからクローズするか。
これ以上行くとC言語の世界に行ってしまうので、一旦やめとこう。