title: PyInstaller-built Windows EXE fails with multiprocessing
body: <p>In my project I'm using Python's <code>multiprocessing</code> library to create multiple processes in __main__. The project is being packaged into a single Windows EXE using PyInstaller 2.1.1.</p>
  
  <p>I create new processes like so:</p>
  
  <pre><code>from multiprocessing import Process
  from Queue import Empty
  
  def _start():
      while True:
          try:
              command = queue.get_nowait()
          # ... and some more code to actually interpret commands
          except Empty:
              time.sleep(0.015)
  
  def start():
      process = Process(target=_start, args=args)
      process.start()
      return process
  </code></pre>
  
  <p>And in __main__:</p>
  
  <pre><code>if __name__ == '__main__':
      freeze_support()
  
      start()
  </code></pre>
  
  <p>Unfortunately, when packaging the application into an EXE and launching it, I get <code>WindowsError</code> 5 or 6 (seems random) at this line:</p>
  
  <pre><code>command = queue.get_nowait()
  </code></pre>
  
  <p>A recipe at PyInstaller's homepage claims that I have to modify my code to enable multiprocessing in Windows when packaging the application as a single file.</p>
  
  <p>I'm reproducing the code here:</p>
  
  <pre><code>import multiprocessing.forking
  import os
  import sys
  
  
  class _Popen(multiprocessing.forking.Popen):
      def __init__(self, *args, **kw):
          if hasattr(sys, 'frozen'):
              # We have to set original _MEIPASS2 value from sys._MEIPASS
              # to get --onefile mode working.
              # Last character is stripped in C-loader. We have to add
              # '/' or '\\' at the end.
              os.putenv('_MEIPASS2', sys._MEIPASS + os.sep)
          try:
              super(_Popen, self).__init__(*args, **kw)
          finally:
              if hasattr(sys, 'frozen'):
                  # On some platforms (e.g. AIX) 'os.unsetenv()' is not
                  # available. In those cases we cannot delete the variable
                  # but only set it to the empty string. The bootloader
                  # can handle this case.
                  if hasattr(os, 'unsetenv'):
                      os.unsetenv('_MEIPASS2')
                  else:
                      os.putenv('_MEIPASS2', '')
  
  
  class Process(multiprocessing.Process):
      _Popen = _Popen
  
  
  class SendeventProcess(Process):
      def __init__(self, resultQueue):
          self.resultQueue = resultQueue
  
          multiprocessing.Process.__init__(self)
          self.start()
  
      def run(self):
          print 'SendeventProcess'
          self.resultQueue.put((1, 2))
          print 'SendeventProcess'
  
  
  if __name__ == '__main__':
      # On Windows calling this function is necessary.
      if sys.platform.startswith('win'):
          multiprocessing.freeze_support()
      print 'main'
      resultQueue = multiprocessing.Queue()
      SendeventProcess(resultQueue)
      print 'main'
  </code></pre>
  
  <p>My frustration with this "solution" is that, one, it's absolutely unclear what exactly it is patching, and, two, that it's written in such a convoluted way that it becomes impossible to infer which parts are the solution, and which are just an illustration.</p>
  
  <p>Can anyone share some light on this issue, and provide insight what exactly needs to be changed in a project that enables multiprocessing in PyInstaller-built single-file Windows executables?</p>