title: Python multiprocessing RemoteManager under a multiprocessing.Process
body: <p>I'm trying to start a data queue server under a managing process (so that it can later be turned into a service), and while the data queue server function works fine in the main process, it does not work in a process created using multiprocessing.Process.</p>
  
  <p>The dataQueueServer and dataQueueClient code is based on the code from the multiprocessing module documentation <a href="http://docs.python.org/library/multiprocessing.html#using-a-remote-manager" rel="noreferrer">here</a>.</p>
  
  <p>When run on its own, <strong>dataQueueServer</strong> works well. However, when run using a <code>multiprocessing.Process</code>'s <code>start()</code> in <strong>mpquueue</strong>, it doesn't work (when tested with the client). I am using the <strong>dataQueueClient</strong> without changes to test both cases.</p>
  
  <p>The code does reach the <code>serve_forever</code> in both cases, so I think the server is working, but something is blocking it from communicating back to the client in the <strong>mpqueue</strong> case.</p>
  
  <p>I have placed the loop that runs the <code>serve_forever()</code> part under a thread, so that it can be stoppable. </p>
  
  <p>Here is the code:</p>
  
  <p><strong>mpqueue</strong> # this is the "manager" process trying to spawn the server in a child process</p>
  
  <pre><code>import time
  import multiprocessing
  import threading
  import dataQueueServer
  
  class Printer():
      def __init__(self):
          self.lock = threading.Lock()
      def tsprint(self, text):
          with self.lock:
              print text
  
  class QueueServer(multiprocessing.Process):
      def __init__(self, name = '', printer = None):
          multiprocessing.Process.__init__(self)
          self.name = name
          self.printer = printer
          self.ml = dataQueueServer.MainLoop(name = 'ml', printer = self.printer)
  
      def run(self):
          self.printer.tsprint(self.ml)
          self.ml.start()
  
      def stop(self):
          self.ml.stop()
  
  if __name__ == '__main__':
      printer = Printer()
      qs = QueueServer(name = 'QueueServer', printer =  printer)
      printer.tsprint(qs)
      printer.tsprint('starting')
      qs.start()
      printer.tsprint('started.')
      printer.tsprint('Press Ctrl-C to quit')
      try:
          while True:
              time.sleep(60)
      except KeyboardInterrupt:
          printer.tsprint('\nTrying to exit cleanly...')
          qs.stop()
  
      printer.tsprint('stopped')
  </code></pre>
  
  <p><strong>dataQueueServer</strong> </p>
  
  <pre><code>import time
  import threading
  
  from multiprocessing.managers import BaseManager
  from multiprocessing import Queue
  
  HOST = ''
  PORT = 50010
  AUTHKEY = 'authkey'
  
  ## Define some helper functions for use by the main process loop
  class Printer():
      def __init__(self):
          self.lock = threading.Lock()
      def tsprint(self, text):
          with self.lock:
              print text
  
  
  
  class QueueManager(BaseManager): 
      pass
  
  
  class MainLoop(threading.Thread):
      """A thread based loop manager, allowing termination signals to be sent
      to the thread"""
      def __init__(self, name = '', printer = None):
          threading.Thread.__init__(self)
          self._stopEvent = threading.Event()
          self.daemon = True
          self.name = name
  
          if printer is None:
              self.printer = Printer()
          else:
              self.printer = printer
  
          ## create the queue
          self.queue = Queue()
          ## Add a function to the handler to return the queue to clients
          self.QM = QueueManager
  
          self.QM.register('get_queue', callable=lambda:self.queue)
          self.queue_manager = self.QM(address=(HOST, PORT), authkey=AUTHKEY)
          self.queue_server = self.queue_manager.get_server()
  
      def __del__(self):
          self.printer.tsprint( 'closing...')
  
  
      def run(self):
          self.printer.tsprint( '{}: started serving'.format(self.name))
          self.queue_server.serve_forever()
  
  
      def stop(self):
          self.printer.tsprint ('{}: stopping'.format(self.name))
          self._stopEvent.set()
  
      def stopped(self):
          return self._stopEvent.isSet()
  
  def start():
      printer = Printer() 
      ml = MainLoop(name = 'ml', printer = printer)
      ml.start()
      return ml
  
  def stop(ml):
      ml.stop()
  
  if __name__ == '__main__':
      ml = start()
      raw_input("\nhit return to stop")
      stop(ml)
  </code></pre>
  
  <p>And a client:</p>
  
  <p><strong>dataQueueClient</strong></p>
  
  <pre><code>import datetime
  from multiprocessing.managers import BaseManager
  
  
  n = 0
  N = 10**n
  
  HOST = ''
  PORT = 50010
  AUTHKEY = 'authkey'
  
  
  def now():
      return datetime.datetime.now()
  
  def gen(n, func, *args, **kwargs):
      k = 0
      while k &lt; n:
          yield func(*args, **kwargs)
          k += 1
  
  class QueueManager(BaseManager): 
      pass
  QueueManager.register('get_queue')
  m = QueueManager(address=(HOST, PORT), authkey=AUTHKEY)
  m.connect()
  queue = m.get_queue()
  
  def load(msg, q):
      return q.put(msg)
  
  def get(q):
      return q.get()
  
  lgen = gen(N, load, msg = 'hello', q = queue)
  t0 = now()
  while True:
      try:
          lgen.next()
      except StopIteration:
          break
  t1 = now()
  print 'loaded %d items in ' % N, t1-t0
  
  t0 = now()
  while queue.qsize() &gt; 0:
      queue.get()
  t1 = now()
  print 'got %d items in ' % N, t1-t0
  </code></pre>