title: outside vs inside __main__ variable definition in multiprocessing
body: <p>I have following code:</p>
  
  <pre><code>import multiprocessing
  import time
  import os
  
  # WHEN SEMAPHORE IS DEFINED HERE THEN IT IT WORKS
  semaphore = multiprocessing.Semaphore(1)
  
  def producer(num, output):
    semaphore.acquire()
    time.sleep(1)
    element = "PROCESS: %d PID: %d PPID: %d" % (num, os.getpid(), os.getppid())
    print "WRITE -&gt; " + element
    output.put(element)
    time.sleep(1)
    semaphore.release()
  
  if __name__ == '__main__':
      """
      Reads elements as soon as they are are put inside queue
      """
  
      output    = multiprocessing.Manager().Queue()
      pool      = multiprocessing.Pool(4)
      lst       = range(40)
  
      # WHEN SEMAPHORE IS DEFINED HERE THEN IT DOES NOT WORKS
      # semaphore = multiprocessing.Semaphore(1)
  
      for i in lst:
          pool.apply_async(producer, (i, output))
          # print "%d Do not wait!" % i
          # res.get()
  
      counter = 0
      while True:
        try:
          print "READ  &lt;- " + output.get_nowait()
          counter += 1
          if (counter == len(lst)):
            print "Break"
            break
        except:
          print "READ  &lt;- NOTHING IN BUFFER"  
          pass
        time.sleep(1)
  </code></pre>
  
  <p>This code is working as expected and it prints:</p>
  
  <pre><code>READ  &lt;- NOTHING IN BUFFER
  WRITE -&gt; PROCESS: 0 PID: 15803 PPID: 15798
  READ  &lt;- NOTHING IN BUFFER
  READ  &lt;- PROCESS: 0 PID: 15803 PPID: 15798
  READ  &lt;- NOTHING IN BUFFER
  WRITE -&gt; PROCESS: 1 PID: 15806 PPID: 15798
  READ  &lt;- PROCESS: 1 PID: 15806 PPID: 15798
  ...
  </code></pre>
  
  <p>Then I have this version which is not working (It is basically the same as first one except the definition of semaphore is in another place):</p>
  
  <pre><code>import multiprocessing
  import time
  import os
  
  # WHEN SEMAPHORE IS DEFINED HERE THEN IT IT WORKS
  # semaphore = multiprocessing.Semaphore(1)
  
  def producer(num, output):
    print hex(id(semaphore))
    semaphore.acquire()
    time.sleep(1)
    element = "PROCESS: %d PID: %d PPID: %d" % (num, os.getpid(), os.getppid())
    print "WRITE -&gt; " + element
    output.put(element)
    time.sleep(1)
    semaphore.release()
  
  if __name__ == '__main__':
      """
      Reads elements as soon as they are are put inside queue
      """
  
      output    = multiprocessing.Manager().Queue()
      pool      = multiprocessing.Pool(4)
      lst       = range(40)
  
      # WHEN SEMAPHORE IS DEFINED HERE THEN IT DOES NOT WORKS
      semaphore = multiprocessing.Semaphore(1)
  
      for i in lst:
          pool.apply_async(producer, (i, output))
          # print "%d Do not wait!" % i
          # res.get()
  
      counter = 0
      while True:
        try:
          print "READ  &lt;- " + output.get_nowait()
          counter += 1
          if (counter == len(lst)):
            print "Break"
            break
        except:
          print "READ  &lt;- NOTHING IN BUFFER"  
          pass
        time.sleep(1)
  </code></pre>
  
  <p>This version prints:</p>
  
  <pre><code>READ  &lt;- NOTHING IN BUFFER
  READ  &lt;- NOTHING IN BUFFER
  READ  &lt;- NOTHING IN BUFFER
  READ  &lt;- NOTHING IN BUFFER
  READ  &lt;- NOTHING IN BUFFER
  READ  &lt;- NOTHING IN BUFFER
  READ  &lt;- NOTHING IN BUFFER
  ...
  </code></pre>
  
  <p>It seems like if <code>producer</code> never writes anything to Queue. I've read somewhere that <code>apply_sync</code> does not print error messages. So I've changed <code>pool.apply_async(producer, (i, output))</code> to <code>pool.apply(producer, (i, output))</code> in second code, to see what is going on. It seems that <code>semaphore</code> is not defined, here is the output:</p>
  
  <pre><code>Traceback (most recent call last):
    File "glob_var_wrong.py", line 31, in &lt;module&gt;
      pool.apply(producer, (i, output))
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 244, in apply
      return self.apply_async(func, args, kwds).get()
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 567, in get
      raise self._value
  NameError: global name 'semaphore' is not defined
  </code></pre>
  
  <p>However following code runs correctly and print 10 (value defined inside <code>__main__</code>):</p>
  
  <pre><code>global_var = 20
  
  def print_global_var():
      print global_var
  
  if __name__ == '__main__':
      global_var = 10
      print_global_var()
  </code></pre>
  
  <p>It seems that in this code global variable can be defined inside <code>__main__</code> while in previous codes it is not possible. First I was assuming that variables defined inside <code>__main__</code> are not shared between processes but it only affects <code>semaphore</code> and not <code>output</code>, <code>pool</code>, <code>lst</code>. Why is this happening?</p>