Как правильно реализовать многопроцессорность в приложении с 4 различными функциями? - PullRequest
0 голосов
/ 04 января 2019

Посмотрите на фрагмент кода ниже.В функции main я создаю массив jobs.Projects - это массив, содержащий несколько project объектов.Эти project объекты также содержат несколько target объектов.Для каждой цели я хочу выполнить четыре разные функции.Для этого я запускаю Process, указывая на функцию run.Я добавляю Process к массиву и запускаю его.Текущий фрагмент кода создаст процессы зомби, которых я стараюсь избегать.

def main():
    jobs = []
    for project in projects:
        for target in project.getTargets():
            p = multiprocessing.Process(target=run, args=(target.getX(),  
                                                          target.getY(),))
            jobs.append(p)
            p.start()

        for job in jobs:
            job.join()

def run(x, y):
    a(x, y)
    b(x, y)
    c(x, y)
    d(x, y)

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

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Из вашего комментария я понимаю, что вы звоните bash в функции a .. d.Я бы предложил , а не , чтобы сделать это.

  1. Если вы делаете вычисления в bash, это лучше сделать на Python.
  2. Если вы используете bash для запуска программ, это также лучше сделать непосредственно в Python.

Если вы можете использовать Python 3, я бы рекомендовал использовать concurrent.futures.ThreadPoolExecutor, чтобы несколько потоков перебирали ваши данные.В каждом потоке вы можете использовать модуль subprocess для запуска внешних программ.Мой скрипт dicom2jpg.py является примером того, как это сделать.Он параллельно запускает программу ImageMagick convert для преобразования рентгеновских изображений DICOM в формат PNG.

Если вам нужно использовать Python 2.7, я бы составил список подпроцессов (вызвав subprocess.Popen).Постоянно перебирайте этот список и проверяйте, завершился ли подпроцесс.Если это так, удалите его из списка.Если у вас не закончились задачи, запустите новый подпроцесс и добавьте его в список.В списке должно быть столько подпроцессов, сколько на вашей машине ядер.Больше вообще не полезно.Этот подход показан в более старой версии dicom2png.py.

0 голосов
/ 04 января 2019

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

from multiprocessing import Pool

def fun(*args)
    proc, p, q = args
    return proc(p, q)

data = [(f, x, y) for f in (a, b, c, d)]
pool = Pool(4)
results = pool.map(fun, data)
...