Su BSD e OS X, puoi usare kqueue con EVFILT_PROC+NOTE_EXIT per fare esattamente questo. Nessun sondaggio richiesto. Sfortunatamente non esiste un equivalente Linux.
Puoi anche creare un socket o un FIFO e leggerli. Il FIFO è particolarmente semplice:collega l'output standard di tuo figlio con il FIFO e leggi. La lettura si bloccherà fino a quando il bambino non esce (per qualsiasi motivo) o fino a quando non emette alcuni dati. Quindi avrai bisogno di un piccolo loop per scartare i dati di testo indesiderati.
Se hai accesso alla fonte del bambino, apri il FIFO per la scrittura quando inizia e poi semplicemente dimenticalo. Il sistema operativo pulirà il descrittore di file aperto quando il figlio termina e il tuo processo "genitore" in attesa si riattiverà.
Ora questo potrebbe essere un processo che non hai avviato o non possiedi. In tal caso, puoi sostituire l'eseguibile binario con uno script che avvii il vero binario ma aggiunga anche il monitoraggio come spiegato sopra.
Finora ho trovato tre modi per farlo su Linux:
- Polling:ogni tanto controlli l'esistenza del processo, utilizzando
kill
o testando l'esistenza di/proc/$pid
, come nella maggior parte delle altre risposte - Usa il
ptrace
chiamata di sistema da collegare al processo come un debugger in modo da ricevere una notifica quando esce, come nella risposta di a3nm - Usa il
netlink
interfaccia per ascoltarePROC_EVENT_EXIT
messaggi - in questo modo il kernel dice al tuo programma ogni volta che un processo termina e tu aspetti solo l'ID di processo corretto. L'ho visto descritto solo in un posto su Internet.
Plug senza vergogna:sto lavorando a un programma (ovviamente open source; GPLv2) che esegue una delle tre.
Niente di equivalente a wait()
. La pratica abituale è eseguire il polling utilizzando kill(pid, 0)
e cercando il valore restituito -1 e errno
di ESRCH
per indicare che il processo è terminato.
Aggiornamento: A partire dal kernel Linux 5.3 esiste una chiamata di sistema pidfd_open, che crea un fd per un dato pid, che può essere interrogato per ricevere una notifica quando pid è terminato.