Python MultiProcessing apply_async ожидает завершения всех процессов - PullRequest
0 голосов
/ 04 декабря 2018

Я пытался управлять серией процессов пакетных файлов параллельно, в то время как существуют зависимые группы подпроцессов.Я надеюсь получить возможность запустить все процессы группы 1 параллельно, а затем дождаться завершения всех из них, прежде чем запускать группу 2 и так далее.Представьте себе серию групп процессов, в которых каждый процесс представляет собой отдельный существующий пакетный файл (batch_i.bat)

У меня есть следующий код, основанный на моем понимании многопроцессорного модуля, поэтому я ожидаю, когда будут вызваны окончательные команды печати,все файлы журнала завершены с точки зрения печати всех чисел.Тем не менее, я заметил, что код Python завершается успешно без завершения пакетных процессов.

Код Python:

import multiprocessing as mp
import subprocess

def worker(cmdlist, log):
    with open(log, 'w') as logfile:
        p = subprocess.Popen(cmdlist, stderr=logfile, stdout=logfile)
    # return p.returncode

# --------------------------------------------
# Main Process (Group 1)
# --------------------------------------------
if __name__ == '__main__':
    group1 = [batch_1 , batch_2 , batch_3 , ..., batch_10]
    group2 = [batch_11, batch_12, batch_13, ..., batch_20]
    group3 = [batch_21, batch_22, batch_23, ..., batch_30]

    # Multi-Core Exec
    all_process = group1 
    all_results = []
    pool = mp.Pool(processes=4)

    for myProcess in all_process:
        print("Starting Process: %s" %myProcess)
        log = os.path.splitext(myProcess)[0] + ".log"
        res = pool.apply_async(worker, args=[myProcess, log])
        all_results.append(res)

    pool.close()
    pool.join()
    print("All sub-processes completed")

    for res in all_results:
        res.get()
    print("All sub-processes completed: %s" % [res.successful() for res in all_results])

# --------------------------------------------
# call group 2 and wait for completion
# --------------------------------------------
....

# --------------------------------------------
# call group 3 and wait for completion
# --------------------------------------------
...

Остальная часть кода вызывает все процессы в группе 2, которые зависят от завершения группы1 и т. Д.


Пакетный файл: batch_i.bat:

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

@echo off
echo Start of Loop

for /L %%n in (1,1,40000) do echo %%n
for /L %%n in (1,1,40000) do echo %%n
for /L %%n in (1,1,40000) do echo %%n
for /L %%n in (1,1,40000) do echo %%n

echo End of Loop

Вывод следующий:

> *** Running Base Cases: ***
>      on 4 CPUs Process: C:\Users\mamo8001\Project\Clustering\01 Codes\testNum.bat Process: C:\Users\mamo8001\Project\Clustering\01
> Codes\testNum2.bat Process: C:\Users\mamo8001\Project\Clustering\01
> Codes\testNum3.bat Process: C:\Users\mamo8001\Project\Clustering\01
> Codes\testNum4.bat Process: C:\Users\mamo8001\Project\Clustering\01
> Codes\testNum.bat Process: C:\Users\mamo8001\Project\Clustering\01
> Codes\testNum2.bat Process: C:\Users\mamo8001\Project\Clustering\01
> Codes\testNum3.bat Process: C:\Users\mamo8001\Project\Clustering\01
> Codes\testNum4.bat 
> All sub-processes completed 
> All sub-processes completed: [True, True, True, True, True, True, True,
> True]
> 
> Process finished with exit code 0

Пока печатаются две последние строки, я замечаю, что в файлах журналов не выводится полный список чисел, т.е.партия не завершена

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Проблема в том, что ваши работники не ждут завершения своих подпроцессов.Добавьте p.wait() после вызова p = subprocess.Popen() в работнике.

0 голосов
/ 04 декабря 2018

Используя восемь пакетных файлов только с одним для цикла до 40000 каждый, я получал те же результаты, пока не запустил Popen в качестве диспетчера контекста.

def worker(cmdlist, log):
    with open(log, 'w') as logfile:
        with subprocess.Popen(cmdlist, stderr=logfile, stdout=logfile) as p:
            pass
    # return p.returncode

Затем два последнихоператоры print не печатали, пока все окна cmd не закрылись.Каждый файл журнала имеет все номера, а также строки начала / конца цикла.

Используемые в качестве диспетчера контекста, документы говорят, что it ожидает завершения процесса.

Если у вас есть Python 3.5+, в документах говорится, что вместо 1011 * нужно использовать subprocess.run(), а в документах .run() явно сказано, что она ожидает завершения команды - я не смог проверить это, у меня естьPython 3.4.


Пакетные файлы были

echo off

echo Start of Loop
for /L %%n in (1,1,40000) do echo %%n
echo End of Loop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...