Я пишу скрипт python (для сред cygwin и linux) для запуска регрессионного тестирования в программе, которая запускается из командной строки с использованием подпроцесса .Popen(). В принципе, у меня есть набор заданий, подмножество которых необходимо запускать в зависимости от потребностей разработчика (порядка от 10 до 1000). Каждая работа может занять от нескольких секунд до 20 минут.Задания динамического переопределения в многопроцессорном пуле в Python
У меня есть работа, выполняющаяся успешно на нескольких процессорах, но я пытаюсь экономить время, разумно упорядочивая задания (исходя из прошлой производительности), чтобы сначала запускать более длинные задания. Усложнение состоит в том, что некоторые работы (расчеты стационарного состояния) должны выполняться перед другими (переходные процессы на основе начальных условий, определяемых установившимся состоянием).
Мой текущий метод обработки этого заключается в том, чтобы возвращать родительское задание и все дочерние задания рекурсивно в один и тот же процесс, но некоторые задания имеют несколько длинных детей. Как только родительское задание будет завершено, я хотел бы добавить детей обратно в пул, чтобы перейти к другим процессам, но их нужно будет добавить в голову очереди. Я не уверен, что смогу это сделать с помощью многопроцессорной обработки. Я искал примеры с Менеджером, но все они основаны на сетевом взаимодействии, и это не особенно применимо. Любая помощь в виде кода или ссылок на хороший учебник по многопроцессорности (я googled ...) была бы высоко оценена. Вот скелет кода для того, что у меня до сих пор, прокомментировал, чтобы указать дочерние задания, которые я хотел бы создать на других процессорах.
import multiprocessing
import subprocess
class Job(object):
def __init__(self, popenArgs, runTime, children)
self.popenArgs = popenArgs #list to be fed to popen
self.runTime = runTime #Approximate runTime for the job
self.children = children #Jobs that require this job to run first
def runJob(job):
subprocess.Popen(job.popenArgs).wait()
####################################################
#I want to remove this, and instead kick these back to the pool
for j in job.children:
runJob(j)
####################################################
def main(jobs):
# This jobs argument contains only jobs which are ready to be run
# ie no children, only parent-less jobs
jobs.sort(key=lambda job: job.runTime, reverse=True)
multiprocessing.Pool(4).map(runJob, jobs)
Случайное примечание: я бы рекомендовал не использовать многопроцессорность здесь, поскольку это не то, для чего он предназначен. Вы можете получить тот же результат с потоками или даже традиционным способом, запускающим и ожидающим процессы (модуль 'subprocess' и' os.wait() '). –