2017-02-15 6 views
1

Я пытаюсь закодировать многопроцессный рекурсивный алгоритм в python 2.7, используя пул рабочих и диспетчера, чтобы разделить очередь между процессами.python рекурсивный алгоритм multiprocess

Чередование всех алгоритмических деталей код выглядит следующим образом одно:

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

Я использую только один работник в бассейне для sakeof простоты. Точно так же с большим количеством рабочих, но беспорядочно. Я ожидал, что выход, как этот:

[] 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

Ваш код может быть проще рассуждать о том, если вы использовали говоря имена для переменных вместо с, v и l. – MKesper

+1

Не уверен, что это должно быть связано с http://docs.python-guide.org/en/latest/writing/gotchas/, но это может быть связано с чем-то. Я бы предложил передать 'None' функции и построить новый список, если' l is None' просто проверить. – Adirio

+0

@MKesper Согласен. Мои компромиссы: 'l' означает« список »,' c' для 'count' и 'v' для 'value'. – Adirio

ответ

0

Любой модуль многопроцессорности или functools выполняет какую-то доработку и отправляет один и тот же изменяемый экземпляр list на два отдельных вызова (link). Должна быть проведена более глубокая проверка, чтобы уведомить об этом beahaviour соответствующему органу. Между тем, используйте 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() 

 Смежные вопросы

  • Нет связанных вопросов^_^