How to find out when a child process died?

In my class, I run 4 processes.

from multiprocessing import Process procs = ( Process(target=ClassOne, name='ClassOne'), Process(target=ClassTwo, name='ClassTwo'), Process(target=ClassThree, name='ClassThree'), Process(target=ClassFour, name='ClassFour'), ) for p in procs: p.daemon = False p.start() 

I would like to be notified when one of my children dies, so I can kill the other and myself.

+6
python synchronization process multiprocessing ipc
source share
5 answers

Just define a signal handler for SIGCHLD , check the frame returned only by the dead child to get the necessary information about it ... and, if necessary, exit () the parent too :)

+3
source share

You can use os.waitpid() , passing -1 as the first argument, and 0 as the second.

  • The first argument means that the request refers to any child of the current process.
  • The second argument means that it behaves like wait() .

The function returns the tuple with pid of the dead child and its exit code.

+3
source share

The easiest way is to explicitly wait for the completion of all processes.

 while multiprocessing.active_children(): pass 

This is not an event, as you might have intended, but it will do the job in your example. Also make sure you import multiprocessing .

+1
source share

You might like the AutoJoiningProcess class in answer to this similar question .

If you are ready to add a dependency on gobject (part of PyGTK) in your code, then AutoJoiningProcess will allow you to listen to the signal that is emitted when the process ends. At this signal, you could answer as you would like.

0
source share

Here is a solution for Windows. It uses the WaitForMultipleObjects call. For Unix, os.waitpid can do the job.

 import multiprocessing as mp import ctypes SYNCHRONIZE = 0x00100000 INFINITE = -1 def mbox(msg): ctypes.windll.user32.MessageBoxW(0, msg, u'spam', 0) if __name__ == '__main__': # start 2 processes procs = [mp.Process(target=mbox, args=(msg,)) for msg in u'ab'] for p in procs: p.start() # wait for at least one process to terminate handles = [ ctypes.windll.kernel32.OpenProcess(SYNCHRONIZE, False, p.pid) for p in procs] array_type = ctypes.c_long * len(handles) handle_array = array_type(*handles) ctypes.windll.kernel32.WaitForMultipleObjects( len(handles), handle_array, False, INFINITE) # terminate the rest for p in procs: p.terminate() # exit print 'done' 
-2
source share

All Articles