Linux のプロセスは親子関係を形成します。シェルは通常、子プロセスを作り、その子が要求されたプログラムを実行するよう整えて外部コマンドを開始します。古典的な説明では、この処理を fork と exec に分けます。
プロセス · レッスン 4
プロセス生成
fork、exec、PID、親子関係が Linux のプロセス生成にどう関わるか学びます。
`fork` で子を作る
fork() システムコールは呼び出し元を基に子プロセスを作ります。親と子は fork の戻り位置から処理を続けますが、異なる戻り値と PID を持ちます。
子は論理的に独立したプロセス状態を得ます。Linux は最初、copy-on-write で物理メモリページを共有し、一方が変更したときだけコピーできます。開いたファイル記述子は継承され、同じ基盤の open file description を参照するため、ファイルオフセットなどが共有されたままの場合があります。
成功した fork() は何を作りますか?
`execve` でプログラムを置き換える
execve() は新しいプログラムを呼び出し元プロセスへ読み込みます。成功するとプロセスイメージを置き換え、古いプログラムへ戻りません。新しいプロセスを作らないため PID は同じです。
多くのシェルコマンドは fork-exec パターンに従います。
- シェルが子を作る。
- 子がリダイレクトなどの実行状態を準備する。
- 子が要求されたプログラムを実行する。
- フォアグラウンドかバックグラウンドかに応じ、シェルが待つか続行する。
ライブラリやアプリケーションは posix_spawn() などの上位インターフェースを公開でき、Linux には clone() など追加の仕組みもあります。fork-exec は唯一の方法ではありませんが、理解に有用なモデルです。
execve() が成功した後、プロセスの PID はどうなりますか?
親と子の ID を調べる
PID はプロセス、PPID は親を識別します。
$ ps -o pid,ppid,stat,cmd
シェルが ps を開始すると、通常そのシェルの PID が ps の PPID に現れます。短命なプロセスは別の観測までに終了する場合があるため、タイミングが重要です。
プロセス一覧の PPID は何を表しますか?
PID 1 と親の付け替え
カーネルは最初のユーザー空間プロセスを PID 1 で開始します。システムによって systemd、別の init、コンテナや PID 名前空間内の小さな init などです。PID 1 はユーザー空間の一部を開始・監督し、シグナルと孤児回収について特別な責任を持ちます。
親が子より先に終了すると、子は PID 名前空間内の適切な subreaper または init プロセスへ付け替えられます。元の親が終わっても、子が終了する必要はありません。
PID 1 について正しい説明はどれですか?
Linux プロセスの管理と監視 では、フォアグラウンド・バックグラウンドコマンドを動かしながら親子 ID を観測できます。
レッスン完了
プロセス生成 を完了しました
古典的な Linux プロセス生成手順を追跡できるようになりました。
fork()で別の PID を持つ子を作る。execve()で PID を変えずプロセスイメージを置き換える。PID と PPID から親子関係を識別する。
PID 1 と subreaper を、親が付け替えられた子の受け入れ先として理解する。