詳細Linuxカーネル プロセス管理周りのシステムコール 7/3
詳細Linuxカーネル プロセス管理周りのシステムコール 7/3
今日は、プロセス管理のシステムコールfork
を見ることにする。
https://kernelreading.doorkeeper.jp/events/44499
プロセス管理は詳解Linuxだと3章辺りなるので、そこを中心に見てみる。
そもプロセスってなんだ?
詳解Linux曰く、
プロセスをプログラムの実行している状態であるとします。
(中略)
カーネルから見ると、プロセスの目的はシステム資源(CPU時間やメモリなど)を割り当てて実体として動かすこと。
プルグラムが何らかの実行単位で処理を実行している状態がプロセス。 この際に必要なリソースは
- 命令コード向けメモリ(テキスト)
- プロセス固有データ領域向けメモリ(スタック/ヒープ)
- プロセッサ状態(コンテキスト):CPUに設定されている情報(SP/PCなど)
辺り。
これらのリソースを各プロセスは所有している。 これに対して、カーネルがプロセスに物理資源(CPU/物理メモリ)をスケジュール管理して割り当てる。
プロセスが生成される時は、基本的にこれらのリソースは親とほぼ同じものを所有している。
ただし、同じものの所有時には、命令コード(テキスト)は共有するが、
それ意外のリソース(スタック/ヒープ)は複製を作成してプログラムを実行する。
このようなプロセスの単位で複数の処理を同時に実行しようとしても、プロセス間での簡単なデータ共有ができない。子プロセスを作る度に、スタック/ヒープといったメモリの複製を作成する必要があり、プロセス作成によるオーバヘッドがある。
なので、データは共有するけど、処理を分けたいという要望があった。そのなかでマルチスレッドの考え方がうまれた。データ領域の一部を共有して複数の処理を同時に実行する。これのような実行形態をマルチスレッドのアプリケーションと呼ぶ。
この考えに対応するためにLinuxでは軽量プロセスを提供している。軽量プロセスでは、幾つかのリソースを共有する。これにより、スレッドのアプリケーションも動作している。
プロセスってどうやって作成するか
カーネルはプロセス生成のためにfork
とexec
の2つのシステムコールを準備している。
fork
は現在のプロセスをコピーして新たなリソースを作成する。exec
は自プロセスを別の実行プログラムを読み込み実行する。
今回はタイトルにも在るように、fork
のシステムコールを読んでいく。
読んでいるkernelは4.2.0
システムコールの呼び出し
毎度ながらLinuxソース上のシステムコールは
SYSCALL_DEFINE
のマクロが使われている。
fork
ももちろん同様で下記のようにソースは記述されている。
#ifdef __ARCH_WANT_SYS_FORK SYSCALL_DEFINE0(fork) { #ifdef CONFIG_MMU return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0); #else /* can not support in nommu mode */ return -EINVAL; #endif } #endif
これを見ると実体は_do_fork
になっており、
clone_flag = SIGCHLD
を指定している。
_do_fork
はその他のclone
やvfork
のシステムコールからも呼び出されるが、処理はclone_flag
にて変わるっぽい。
こっから先はざっと目を通したのみ。(全然進んでいない・・・)
とりあえず、fork
とclone
で違いが在る部分、言い換えれば、clone_flag
にて処理が変わっている部分に着目してみる。
_do_fork
の処理は下記の通リ
ってところで時間切れ。 とりあえず、なんとなくでもプロセスとスレッドの関係がわかって良かった。