python递归算法多进程

时间:2017-02-15 10:34:41

标签: python recursion python-multiprocessing

我正在尝试在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版本。 我已经在网上寻找解决方案,但我没有找到任何东西。

任何帮助将不胜感激。

1 个答案:

答案 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()