我正在尝试在python 2.7中编写一个多进程递归算法,使用工作池和管理器在进程间共享队列。
划分出所有算法细节,代码如下所示:
from functools import partial
from multiprocessing import Pool, Manager
def pulse(l, c, accOut, v):
print l, c, v
if c < 3:
c = c + 1
l.append((v,c))
pulse(l, c, accOut, v)
else:
accOut.put(l)
return
if __name__ == "__main__":
pool = Pool(processes=1)
manager = Manager()
accOut = manager.Queue()
lNodes = manager.list(range(1, 7))
partialCall = partial(pulse, list(), 0, accOut)
pool.map(partialCall, lNodes)
pool.close()
pool.join()
print "--- Lists in the queue: "
while not accOut.empty():
print accOut.get()
为了简单起见,我只在池中使用一名工作人员。这与更多的工人一样,但更加混乱。 我期待像这样的输出:
[] 0 1
[(1, 1)] 1 1
[(1, 1), (1, 2)] 2 1
[(1, 1), (1, 2), (1, 3)] 3 1
[] 0 2
[(2, 1)] 1 2
[(2, 1), (2, 2)] 2 2
[(2, 1), (2, 2), (2, 3)] 3 2
[] 0 3
[(3, 1)] 1 3
[(3, 1), (3, 2)] 2 3
[(3, 1), (3, 2), (3, 3)] 3 3
[] 0 4
[(4, 1)] 1 4
[(4, 1), (4, 2)] 2 4
[(4, 1), (4, 2), (4, 3)] 3 4
[] 0 5
[(5, 1)] 1 5
[(5, 1), (5, 2)] 2 5
[(5, 1), (5, 2), (5, 3)] 3 5
[] 0 6
[(6, 1)] 1 6
[(6, 1), (6, 2)] 2 6
[(6, 1), (6, 2), (6, 3)] 3 6
--- Lists in the queue:
[(1, 1), (1, 2), (1, 3)]
[(2, 1), (2, 2), (2, 3)]
[(3, 1), (3, 2), (3, 3)]
[(4, 1), (4, 2), (4, 3)]
[(5, 1), (5, 2), (5, 3)]
[(6, 1), (6, 2), (6, 3)]
相反,我得到这样的东西:
[] 0 1
[(1, 1)] 1 1
[(1, 1), (1, 2)] 2 1
[(1, 1), (1, 2), (1, 3)] 3 1
[(1, 1), (1, 2), (1, 3)] 0 2
[(1, 1), (1, 2), (1, 3), (2, 1)] 1 2
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2)] 2 2
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)] 3 2
[] 0 3
[(3, 1)] 1 3
[(3, 1), (3, 2)] 2 3
[(3, 1), (3, 2), (3, 3)] 3 3
[(3, 1), (3, 2), (3, 3)] 0 4
[(3, 1), (3, 2), (3, 3), (4, 1)] 1 4
[(3, 1), (3, 2), (3, 3), (4, 1), (4, 2)] 2 4
[(3, 1), (3, 2), (3, 3), (4, 1), (4, 2), (4, 3)] 3 4
[] 0 5
[(5, 1)] 1 5
[(5, 1), (5, 2)] 2 5
[(5, 1), (5, 2), (5, 3)] 3 5
[(5, 1), (5, 2), (5, 3)] 0 6
[(5, 1), (5, 2), (5, 3), (6, 1)] 1 6
[(5, 1), (5, 2), (5, 3), (6, 1), (6, 2)] 2 6
[(5, 1), (5, 2), (5, 3), (6, 1), (6, 2), (6, 3)] 3 6
--- Lists in the queue:
[(1, 1), (1, 2), (1, 3)]
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)]
[(3, 1), (3, 2), (3, 3)]
[(3, 1), (3, 2), (3, 3), (4, 1), (4, 2), (4, 3)]
[(5, 1), (5, 2), (5, 3)]
[(5, 1), (5, 2), (5, 3), (6, 1), (6, 2), (6, 3)]
我不明白。为何输出?我究竟做错了什么?为什么,当用v = 2调用脉冲函数时,不会将新列表作为输入?我应该以不同的方式传递部分功能中的列表吗?
我可以很容易地获得在脉冲函数的第一次调用中重置列表l的预期结果,但我认为它不干净并且必须有另一种方法来执行此操作。
我在Windows 10 64bit工作,无法更改python版本。 我已经在网上寻找解决方案,但我没有找到任何东西。
任何帮助将不胜感激。
答案 0 :(得分:0)
多处理或functools模块正在进行某种批处理并将相同的可变list
实例发送到两个单独的调用(link)。应进行更深入的检查,以便将此行为通知相应的实体。同时,使用None
作为参数,并在第一个list
迭代中生成pulse
的实例。
from functools import partial
from multiprocessing import Pool, Manager
def pulse(l, c, accOut, v):
if l is None:
l = []
print l, c, v
if c < 3:
c = c + 1
l.append((v,c))
pulse(l, c, accOut, v)
else:
accOut.put(l)
return
if __name__ == "__main__":
pool = Pool(processes=1)
manager = Manager()
accOut = manager.Queue()
lNodes = manager.list(range(1, 7))
partialCall = partial(pulse, None, 0, accOut)
pool.map(partialCall, lNodes)
pool.close()
pool.join()
print "--- Lists in the queue: "
while not accOut.empty():
print accOut.get()
您可能实际上想要交换参数顺序以为其中一些提供默认值:
from functools import partial
from multiprocessing import Pool, Manager
def pulse(accOut, v, l=None, c=0):
if l is None:
l = []
print l, c, v
if c < 3:
c = c + 1
l.append((v,c))
pulse(accOut, v, l, c)
else:
accOut.put(l)
return
if __name__ == "__main__":
pool = Pool(processes=1)
manager = Manager()
accOut = manager.Queue()
lNodes = manager.list(range(1, 7))
partialCall = partial(pulse, accOut)
pool.map(partialCall, lNodes)
pool.close()
pool.join()
print "--- Lists in the queue: "
while not accOut.empty():
print accOut.get()