title: Python Multiprocessing Queue Error: 'function' object has no attribute 'put'
body: <p>The code is supposed to derive PI using monte carlo method parallelized across 7 processes. </p>
  
  <p>Here is the first error I am getting:</p>
  
  <pre><code>/usr/bin/python3.6 /home/hirshad/JupyterProjects/ParallelPI/MultiprocessingPI.py
  Starting main program
  Starting controller
  Starting worker Worker-1
  Starting worker Worker-2
  Starting worker Worker-3
  Starting worker Worker-4
  Starting worker Worker-5
  Starting worker Worker-6
  Starting worker Worker-7
  Process Worker-7:
  Traceback (most recent call last):
    File "/usr/lib/python3.6/multiprocessing/process.py", line 258, in _bootstrap
      self.run()
    File "/home/hirshad/JupyterProjects/ParallelPI/MultiprocessingPI.py", line 24, in run
      self.queue.put(countIn)
  AttributeError: 'function' object has no attribute 'put'
  countIn is 76406243
  countIn is 76401925
  </code></pre>
  
  <p>The code is</p>
  
  <pre><code>import multiprocessing
  import time
  import random as rd
  
  
  class Worker(multiprocessing.Process):
  
      def __init__(self, queue):
          multiprocessing.Process.__init__(self)
          self.queue = queue
  
      def run(self):
          print("Starting worker " + self.name)
          countIn = 0
          rSquared = 10000
          reach = 100000000
          for iteration in range(reach):
              x = rd.randint(0, 101)
              y = rd.randint(0, 101)
              if ((x * x) + (y * y)) &lt; rSquared:
                  countIn += 1
  
          print("countIn is " + str(countIn))
          self.queue.put(countIn) #ERROR HERE
  
  
  class Controller(multiprocessing.Process):
  
      def __init__(self):
          self.queue = multiprocessing.Queue
          self.reach = 700000000
  
      def run(self):
          print("Starting controller")
          workers = []
          countInTotal = 0
  
          for i in range(7):
              w = Worker(self.queue)
              w.start()
              workers.append(w)
          for i in workers:
              i.join()
          if self.queue.qsize() is not 7:
              print("sleeping for 30 seconds")
              time.sleep(30)
          else:
              for i in range(7):
                  countInTotal = countInTotal + self.queue.get()
          print("PI is " + str(4*(countInTotal/self.reach)))
  
  
  if __name__=='__main__':
      print("Starting main program")
      c = Controller()
      c.run()
      c.join()
  </code></pre>
  
  <p>The idea is to use a controller class to manage the workers that will calculate solution parameters in parallel and put to the shared queue. Once the queue reaches desired size of number of workers(7), the controller pops from the queue and sums up the values. </p>
  
  <p>According to <a href="https://docs.python.org/2/library/multiprocessing.html" rel="nofollow noreferrer">https://docs.python.org/2/library/multiprocessing.html</a>, Python's multiprocessing library has a queue object for process to process communication. <code>self.queue.put(countIn)</code> should reference the queue object passed by and created by the controller object. The error seems to refer to a function object, but isn't queue a non function object?</p>
  
  <p>EDIT: The issue is in controller class, <code>self.queue = multiprocessing.Queue</code>, the Queue class is being passed, not a queue object.</p>
  
  <p>Making a few more bug fixes to make the code work, here is a working solution:</p>
  
  <pre><code>import multiprocessing
  import random as rd
  
  
  class Worker(multiprocessing.Process):
  
      def __init__(self, queue):
          multiprocessing.Process.__init__(self)
          self.queue = queue
  
      def run(self):
          print("Starting worker " + self.name)
          countIn = 0
          rSquared = 10000
          reach = 100000000
          for iteration in range(reach):
              x = rd.randint(0, 101)
              y = rd.randint(0, 101)
              if ((x * x) + (y * y)) &lt; rSquared:
                  countIn += 1
  
          print("countIn is " + str(countIn))
          self.queue.put(countIn)
  
  
  class Controller(multiprocessing.Process):
  
      def __init__(self):
          self.queue = multiprocessing.Queue()
          self.reach = 700000000
  
      def run(self):
          print("Starting controller")
          workers = []
          countInTotal = 0
  
          for i in range(7):
              w = Worker(self.queue)
              w.start()
              workers.append(w)
  
          for i in workers:
              i.join()
  
          for i in range(7):
              countInTotal = countInTotal + self.queue.get()
  
          print("PI is " + str(4*(countInTotal/self.reach)))
  
  
  if __name__=='__main__':
      print("Starting main program")
      c = Controller()
      c.run()
  </code></pre>