Auf BSDs und OS X können Sie kqueue mit EVFILT_PROC+NOTE_EXIT verwenden, um genau das zu tun. Keine Abfrage erforderlich. Leider gibt es kein Linux-Äquivalent.
Sie könnten auch einen Socket oder einen FIFO erstellen und darauf lesen. Der FIFO ist besonders einfach:Verbinden Sie den Standardausgang Ihres Kindes mit dem FIFO und lesen Sie ihn aus. Der Lesevorgang wird blockiert, bis das untergeordnete Element (aus irgendeinem Grund) beendet wird oder bis es einige Daten ausgibt. Sie brauchen also eine kleine Schleife, um die unerwünschten Textdaten zu verwerfen.
Wenn Sie Zugriff auf die Quelle des Kindes haben, öffnen Sie das FIFO zum Schreiben, wenn es beginnt, und vergessen Sie es dann einfach. Das Betriebssystem bereinigt den geöffneten Dateideskriptor, wenn das Kind beendet wird, und Ihr wartender "Eltern"-Prozess wird aufwachen.
Nun, dies könnte ein Prozess sein, den Sie nicht gestartet haben oder dessen Eigentümer Sie nicht sind. In diesem Fall können Sie die ausführbare Binärdatei durch ein Skript ersetzen, das die eigentliche Binärdatei startet, aber auch die oben beschriebene Überwachung hinzufügt.
Bisher habe ich drei Möglichkeiten gefunden, dies unter Linux zu tun:
- Polling:Sie überprüfen von Zeit zu Zeit, ob der Prozess existiert, entweder mit
kill
oder durch Testen auf das Vorhandensein von/proc/$pid
, wie in den meisten anderen Antworten - Verwenden Sie den
ptrace
Systemaufruf zum Anhängen an den Prozess wie ein Debugger, damit Sie benachrichtigt werden, wenn er beendet wird, wie in der Antwort von a3nm - Verwenden Sie den
netlink
Schnittstelle, um aufPROC_EVENT_EXIT
zu lauschen Nachrichten - auf diese Weise teilt der Kernel Ihrem Programm jedes Mal mit, wenn ein Prozess beendet wird, und Sie warten nur auf die richtige Prozess-ID. Ich habe dies nur an einer Stelle im Internet beschrieben gesehen.
Schamloser Plug:Ich arbeite an einem Programm (natürlich Open Source; GPLv2), das eines der drei macht.
Nichts Äquivalent zu wait()
. Die übliche Vorgehensweise ist die Abfrage mit kill(pid, 0)
und nach dem Rückgabewert -1 und errno
suchen von ESRCH
um anzuzeigen, dass der Vorgang abgeschlossen ist.
Aktualisierung: Seit dem Linux-Kernel 5.3 gibt es einen pidfd_open-Systemaufruf, der ein fd für eine gegebene PID erstellt, das abgefragt werden kann, um eine Benachrichtigung zu erhalten, wenn PID beendet wurde.