なぜ調べたか(どういう観点から調べる必要があったか)
知り合いに thread と process の違いを解説していた際に、親プロセスはどのようにして子プロセスを識別しているのかという話になった。 これは親プロセスが子プロセスを生成したあとに、子プロセスがクラッシュし、別のプロセスが当初の子プロセスのPIDを引き継いだ場合に識別できるのか? という質問があった PIDが短時間で重複するとは考えにくいが、デーモンとして長期間動くような場合に考えられない動作ではないため、どのようにして子プロセスと認識しているのかを調べる
どこを調べたか
- google でプロセスグループについて調べた
- google で linux pid 重複で調べた
- https://ja.stackoverflow.com/questions/56177/%E3%81%82%E3%82%8B%E6%99%82%E5%88%BB%E3%81%AE-%E7%89%B9%E5%AE%9A%E3%81%AE-pid-%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%A8-%E5%88%A5%E3%81%AE%E6%99%82%E5%88%BB%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E5%90%8C%E3%81%98-pid-%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E3%81%AE%E5%90%8C%E4%B8%80%E6%80%A7%E3%81%AE%E5%88%A4%E5%AE%9A%E3%81%AF%E3%81%A7%E3%81%8D%E3%82%8B/56182
- https://w0.hatenablog.com/entry/2021/04/13/023513
- 別の知り合いにこの件について質問して、OSはpidでのみ管理しているんじゃないかという話があり、pidは親プロセスが回収するまでゾンビプロセスとして動くのではということであった
調べた結果得られた答えはなんだったのか
- 結論として、意図せず子プロセスの pid が再利用されることは通常の実装であればありえない
- これを理解するためにはまず、親プロセスと子プロセスの挙動について知る必要がある
- 親プロセスは通常、forkによって子プロセスを生成する場合 waitpid や wait で子プロセスの状況を待つ必要がある
- waitpidやwaitをおこなない場合に子プロセスが死んだ場合はゾンビプロセスとして扱われる
- ゾンビプロセスとして動き続けるため、pidが別のプロセスによってしようされることはない
- 親プロセスは通常、forkによって子プロセスを生成する場合 waitpid や wait で子プロセスの状況を待つ必要がある
- waitpid したあと WIFEXITED や WIFSIGNALEDによって終了を検出することができ、子プロセスの終了を適切にハンドリングしていれば、pidが別のプロセスによって再利用される前にハンドリングできる
- 親プロセスがwait, waitpid をする前死んだ場合は孤児プロセスとして、Systemd環境下ではsystemd --userの子プロセスとなる
- 検証コード: https://github.com/bootjp/playground/blob/main/pid_test/orphan.c
- webによくある記事としては init, systemdに回収されたあと子プロセスにkillをしても死なないとあるが、以下の環境ではkillで死ぬことが確認できた
- uname -a
Linux manjaro 5.9.16-1-MANJARO #1 SMP PREEMPT Mon Dec 21 22:00:46 UTC 2020 x86_64 GNU/Linux
- systemctl --version
systemd 247 (247.6-1.0-manjaro)
+PAM +AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +ZSTD +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid
関連する技術はどういうものか
- fork(2)
- waitpid
- プロセス
- プロセステーブル
- プロセスグループ
- systemd
- init