プロセスとスレッド ~徒然なるままに~
本記事はUNIX/Linux系OSを、プログラミング言語はC言語を想定する。
プロセスはOSが管理するメモリ管理を単位とす。
初期プロセスとしてInitプロセスが起動し、全てのプロセスはこのプロセスの祖先となる。
プロセスはforkシステムコールにて生成される。
forkシステムコールを呼ぶとOSはそれを呼んだプロセスのメモリコピーを行い、
プロセステーブルに登録して実行待機状態としてタスクスケジューラに登録する。
呼ばれたプロセスはexecシステムコールによって実行されるロードモジュールにメモリを置き換える。
注意すべき点は、実行モジュールが小さくとも親プロセスが大量のメモリを使用している場合、
一時的にしろその複製が作られるという点にある。
つまりfork-execによるプロセス生成・実行にはオーバーヘッドがかかるということである。
そこで生まれたのが軽量プロセスと呼ばれるスレッドの概念である。
プロセスは閉じた論理アドレス内で動き、プロセス間でデータを共有する場合はプロセス間通信が必要であるが、
スレッドはその必要なく生成され、実行単位となるCPUの割り当て単位となるスケジューラに登録される。
プロセスのデータ記憶域は、グローバル・スタック(レジスタ含む)・ヒープの3つに分類されるが、
プロセス内で生成されたスレッドは個々にスタック(レジスタ含む)のみ独立し、グローバル・ヒープは
プロセス内の他のスレッドと共有される。
プロセス生成時に伴い確保されるスレッドは初期スレッド、メインスレッドなどと呼ばれる。
スレッド間のデータの共有は同じ論理アドレスにてグローバル、ヒープをアクセスできるため、
生成・実行のオーバーヘッドがプロセスに比べ小さいため、軽量プロセスとも呼ばれる所以である。
実際の子スレッドのスタックはヒープ領域の論理アドレス空間を使う。
OSカーネル自体もスレッドで動作しており、カーネルスレッドと呼ばれる。
大抵はスタックサイズは1KB以内に抑えられ、スタックオーバーフローを起こすとカーネルパニックを引き起こす。
通常のユーザスレッドがオーバーフローを起こす場合は、OSが管理している論理空間内のメモリを壊すだけなので
せいぜいがプロセス異常終了に留まる。
ざっくりプロセスとスレッドに述べるとこんな感じ。
これを読んだ人の中には、何だ、こんなものかと思われるかもしれない。
計算機の中は複雑と思われるかもしれないが、思ったほど複雑ではなく、我々の脳から比べればはるかに単純である。
スレッドで泣く人たちは、大抵は排他制御で苦しむのである。
以上、徒然なるままにプロセスとスレッドについて記載してみた。
気が向けば、他のトピックについても、徒然なるままに記載してみようと思う。
※コメント投稿者のブログIDはブログ作成者のみに通知されます