BSD および OS X では、kqueue を EVFILT_PROC+NOTE_EXIT とともに使用して、まさにそれを行うことができます。ポーリングは必要ありません。残念ながら、Linux に相当するものはありません。
ソケットまたは FIFO を作成して、それらを読み取ることもできます。 FIFO は特に単純です。子の標準出力を FIFO に接続して読み取ります。読み取りは、子プロセスが (何らかの理由で) 終了するか、何らかのデータを発行するまでブロックされます。そのため、不要なテキスト データを破棄するための小さなループが必要になります。
子のソースにアクセスできる場合は、開始時に FIFO を書き込み用に開き、その後は単に忘れてください。子が終了すると、OS は開いているファイル記述子を消去し、待機中の「親」プロセスが起動します。
これは、あなたが開始または所有していないプロセスである可能性があります。その場合、バイナリ実行可能ファイルを、実際のバイナリを開始するスクリプトに置き換えることができますが、上記で説明したように監視も追加します。
これまでのところ、Linux でこれを行う 3 つの方法を見つけました。
- ポーリング:
kill
を使用して、プロセスの存在を頻繁にチェックします。 または/proc/$pid
の存在をテストすることによって 、他のほとんどの回答と同様 ptrace
を使用する a3nmの回答のように、デバッガのようにプロセスにアタッチするシステムコールにより、プロセスが終了したときに通知を受け取りますnetlink
を使用するPROC_EVENT_EXIT
をリッスンするインターフェース メッセージ - このようにして、プロセスが終了するたびにカーネルがプログラムに通知し、正しいプロセス ID を待つだけです。これについて説明されているのは、インターネット上の 1 か所でしか見たことがありません。
恥知らずなプラグ:私は 3 つのいずれかを実行するプログラム (もちろんオープン ソース; GPLv2) に取り組んでいます。
wait()
に相当するものはありません . kill(pid, 0)
を使用してポーリングするのが通常の方法です。 戻り値 -1 と errno
を探します ESRCH
の プロセスが終了したことを示します。
更新: Linux カーネル 5.3 以降では、pid が終了したときに通知を受け取るためにポーリングできる、指定された pid の fd を作成する pidfd_open syscall があります。