Multiprocessing.Process Daemonic Behavior

John L. Stephens lists.jkstephens at gmail.com
Tue Mar 15 22:34:25 EDT 2011


Greetings,

I'm trying to understand the behavior of the multiprocessing.Process 
daemonic attribute.

Based on what I have read, if a Process ( X ) is created, and before it 
is started ( X.start() ), I should be able to set the process as 
daemonic using X.daemon=True.

Once this attribute is set, if the parent process terminates, all 
daemonic process should also terminate.

To experiment with this, I have written the following script.
#-- BEGIN SCRIPT --#
#!/usr/bin/env python

from time import sleep
from os import getpid
from multiprocessing import Process

class worker(Process):
     def __init__(self, id):
         Process.__init__(self)
         self.id = id

     def run(self):
         try:
             print 'Starting thread %s (pid:%s)' % (self.id, getpid())
             while True:
                 print 'Hello from thread %s (pid:%s)' % (self.id, getpid())
                 sleep(1)
         except KeyboardInterrupt:
             print '****** KeyboardInterrupt captured.  Shutting down 
thread %d (pid:%s) ' % (self.id, getpid())

if __name__ == '__main__':
     print 'Starting main (pid:%s)' % ( getpid())
     t = []
     try:
         for i in range(2):
             w = worker(i)
             w.daemon=True
             if w._daemonic: print 'thread %d is daemonic' % i
             t.append(w)
         try:
             for i in range(len(t)):
                 t[i].start()
             loop = True
             while loop:
                 loop = False
                 for i in range(len(t)):
                     if t[i].is_alive(): loop = True
                     if not t[i]._daemonic: print 'thread %d is NOT 
daemonic' % i
                 sleep(1)
         except KeyboardInterrupt: raise
     except KeyboardInterrupt:
         print  'KeyboardInterrupt captured.  Shutting down main 
(pid:%s)' % getpid()

     print 'Shutting down'
     sleep(10)
     print 'Done.'
# -- END SCRIPT -- #

 From the command line, if I run the script and then enter ctrl-C the 
program and daemonic children terminate as I would expect.
~/temp$ ./threadtest.py
Starting main (pid:13395)
thread 0 is daemonic
thread 1 is daemonic
Starting thread 0 (pid:13396)
Hello from thread 0 (pid:13396)
Starting thread 1 (pid:13397)
Hello from thread 1 (pid:13397)
Hello from thread 0 (pid:13396)
Hello from thread 1 (pid:13397)
Hello from thread 0 (pid:13396)
Hello from thread 1 (pid:13397)
Hello from thread 0 (pid:13396)
Hello from thread 1 (pid:13397)
Hello from thread 0 (pid:13396)
Hello from thread 1 (pid:13397)
^C
KeyboardInterrupt captured.  Shutting down main (pid:13395)
Shutting down
****** KeyboardInterrupt captured.  Shutting down thread 0 (pid:13396)
****** KeyboardInterrupt captured.  Shutting down thread 1 (pid:13397)
Done.

Likewise, if i use a 'kill -2  13395', the results are the same (13395 
being the parent pid).
If I use a 'kill -2 13396 13397', the daemonic children terminate, and 
the main closes as one would expect (13396 and 13397 being the children 
pids).

However, if I use a 'kill 13395' (or something other then a SIGINT) the 
parent process terminates and the daemonic children CONTINUE TO 
PROCESS.  The children essentially become zombies merrily meandering 
around the system.  Really, is there anything worse then a daemonic zombie?

I would have expected the daemonic children processes to terminate with 
the parent process, regardless of how the parent process terminates, 
either normally or forcefully.

I would love to be enlightened....

Thanks.





More information about the Python-list mailing list