title: Python Process won't call atexit
body: <p>I'm trying to use <code>atexit</code> in a <code>Process</code>, but unfortunately it doesn't seem to work. Here's some example code:</p>
  
  <pre><code>import time
  import atexit
  import logging
  import multiprocessing
  
  logging.basicConfig(level=logging.DEBUG)
  
  class W(multiprocessing.Process):
      def run(self):
          logging.debug("%s Started" % self.name)
  
          @atexit.register
          def log_terminate():
               # ever called?
               logging.debug("%s Terminated!" % self.name)
  
          while True:
              time.sleep(10)
  
  @atexit.register
  def log_exit():
      logging.debug("Main process terminated")
  
  logging.debug("Main process started")
  
  a = W()
  b = W()
  a.start()
  b.start()
  time.sleep(1)
  a.terminate()
  b.terminate()
  </code></pre>
  
  <p>The output of this code is:</p>
  
  <pre>
  DEBUG:root:Main process started
  DEBUG:root:W-1 Started
  DEBUG:root:W-2 Started
  DEBUG:root:Main process terminated
  </pre>
  
  <p>I would expect that the <code>W.run.log_terminate()</code> would be called when <code>a.terminate()</code> and <code>b.terminate()</code> are called, and the output to be something likeso (emphasis added)!:</p>
  
  <pre>
  DEBUG:root:Main process started
  DEBUG:root:W-1 Started
  DEBUG:root:W-2 Started
  <b>DEBUG:root:W-1 Terminated!
  DEBUG:root:W-2 Terminated!</b>
  DEBUG:root:Main process terminated
  </pre>
  
  <p>Why isn't this working, and is there a better way to log a message (from the <code>Process</code> context) when a <code>Process</code> is terminated?</p>
  
  <p>Thank you for your input - it's much appreciated.</p>
  
  <h1>Solution</h1>
  
  <p><b>EDIT: </b> Based on solution suggested by Alex Martelli, the following works as expected:</p>
  
  <pre><code>import sys
  import time
  import atexit
  import signal
  import logging
  import multiprocessing
  
  logging.basicConfig(level=logging.DEBUG)
  
  class W(multiprocessing.Process):
      def run(self):
          logging.debug("%s Started" % self.name)
  
          def log_terminate(num, frame):
               logging.debug("%s Terminated" % self.name)
               sys.exit()
          signal.signal(signal.SIGTERM, log_terminate)
          while True:
              time.sleep(10)
  
  @atexit.register
  def log_exit():
      logging.debug("Main process terminated")
  
  logging.debug("Main process started")
  a = W()
  b = W()
  a.start()
  b.start()
  time.sleep(1)
  a.terminate()
  b.terminate()
  </code></pre>
  
  <p>It's worthwhile to note the following comment in the <code><a href="http://docs.python.org/library/atexit.html" rel="noreferrer">atexit</a></code> documentation:</p>
  
  <blockquote>Note: the functions registered via this module are not called when the program is killed by a signal, when a Python fatal internal error is detected, or when os._exit() is called.</blockquote>