该代码应该使用跨7个进程并行化的蒙特卡洛方法派生PI。
这是我遇到的第一个错误:
/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
代码是
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)) < 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()
这个想法是使用控制器类来管理将并行计算解决方案参数并将其放入共享队列的工作程序。一旦队列达到所需数目的worker(7)大小,控制器就会从队列中弹出并汇总值。
根据https://docs.python.org/2/library/multiprocessing.html,Python的多处理库具有用于处理通信的进程的队列对象。 self.queue.put(countIn)
应该引用控制器对象传递和创建的队列对象。该错误似乎是指一个功能对象,但是不是将非功能对象排队吗?
编辑:问题出在控制器类self.queue = multiprocessing.Queue
中,正在传递Queue类,而不是队列对象。
为了使代码正常工作,还进行了一些错误修复,这是一个可行的解决方案:
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)) < 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()