Многопроцессорная обработка Python - проблема с пустой очередью и зависанием пула - PullRequest
0 голосов
/ 06 февраля 2019

У меня проблемы с многопроцессорной обработкой Python

Python версии 3.6.6

с использованием Spyder IDE в Windows 7

1.

очередь не выполняетсязаполненный -> каждый раз, когда я пытаюсь прочитать его, он пуст.Где-то я читал, что я должен получить () его до процесса join (), но он не решил его.

from multiprocessing import Process,Queue

# define a example function
def fnc(i, output):    
    output.put(i)    

if __name__ == '__main__':
    # Define an output queue
    output = Queue()

    # Setup a list of processes that we want to run
    processes = [Process(target=fnc, args=(i, output)) for i in range(4)]
    print('created')

    # Run processes
    for p in processes:
        p.start()
    print('started')

    # Exit the completed processes        
    for p in processes:
        p.join()

    print(output.empty())
    print('finished')

>>>created
>>>started
>>>True
>>>finished

Я ожидал бы, что вывод не будет пустым.

, если яизмените его с .join () на

    for p in processes:
        print(output.get())
        #p.join()

он зависает

2.

Следующая проблема у меня с pool.map () - он зависает и не имеетшанс превысить лимит памяти.Я даже не знаю, как отлаживать такой простой кусок кода.

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)
    print('Pool created')
    # print "[0, 1, 4,..., 81]"
    print(pool.map(f, range(10))) # it freezes here

Надеюсь, не так уж и сложно иметь два вопроса в одной теме

1 Ответ

0 голосов
/ 06 февраля 2019

По-видимому, проблема в консоли IPython Spyder.Когда я запускаю оба из cmd, он выполняется правильно.


Решение

для отладки в Spyder добавляет .dummy к многопроцессорному импорту

from multiprocessing.dummy import Process,Queue

Это не будетбудет выполняться несколькими процессорами, но вы получите результаты и сможете увидеть результат.После завершения отладки просто удалите .dummy, поместите его в другой файл, импортируйте его и, например, вызовите как функцию

multiprocessing_my.py

from multiprocessing import Process,Queue

# define a example function
def fnc(i, output):
    output.put(i)
    print(i)

def test():
    # Define an output queue
    output = Queue()
    # Setup a list of processes that we want to run
    processes = [Process(target=fnc, args=(i, output)) for i in range(4)]
    print('created')
    # Run processes
    for p in processes:
        p.start()
    print('started')
    # Exit the completed processes

    for p in processes:    
        p.join()

    print(output.empty())
    print('finished')

    # Get process results from the output queue
    results = [output.get() for p in processes]
    print('get results')
    print(results)

test_mp.py

выполняется путем выбора кода и нажатия Ctrl + Enter

import multiprocessing_my

multiprocessing_my.test2()

...

In[9]: test()
    created
    0
    1
    2
    3
    started
    False
    finished
    get results
    [0, 1, 2, 3]
...