テクノロジー · 実用ガイド
Python subprocess がタイムアウト後も子孫を残す?process group と pipe を監査する
terminate、group signal、再帰的 cleanup を選ぶ前に、direct child、descendants、session、PGID、継承 pipe writer を追跡する。

タイムアウトは待機が期限を超えたことだけを示し、仕事が一つの PID だけか、全子孫が同じ group にいるか、stdout と stderr の writer が消えたかは証明しない。
一つの launch token で topology と pipe state を保存し、仕事を本当に所有する最小の platform primitive を使う。短い grace period 後にだけ escalation し、実際の launcher で exit と closure を確認する。
cleanup 前に証拠を固定する
launch token、親と direct child の PID、PPID chain、command、start time、session、PGID、shell/capture 設定を leader 終了前に記録する。
leader の生死、残存 descendants、communicate が open pipe を待つかを別々に記録する。
PID ではなく ownership unit を選ぶ
単一 process なら direct-child contract で足りるが、shell、worker、build tool では POSIX group、recursive set、Windows job などを定義する。
未確認 PID から推測した group を signal しない。leader と membership を記録し、無関係な service を外す。
自分が作った POSIX group だけを制御する
tree 全体を所有する場合は start_new_session=True を使える。timeout 後は確認済み group に graceful signal、bounded wait、escalation、reap の順で行う。
threaded app で preexec_fn を安易に使わず、documented parameter を使う。descendant が別 session を作る可能性も再確認する。
継承 pipe を別の shutdown gate にする
全 writer が閉じるまで capture pipe は EOF にならない。shell や helper は direct child 終了後も handle を保持できる。
TimeoutExpired の partial output を保存し、確認済み writer を処理してから drain する。
platform branch で結果を証明する
適切な group がない場合、psutil で早期に recursive descendants を snapshot し、terminate、wait、kill と identity check を行う。
実 launcher で timeout を再現し、child/tree 消滅、pipe closure、output policy、reap、unrelated sentinel 生存を確認する。
