Как можно запустить несколько вычислений параллельно, остановив их все, когда вернется первый? [Python] - PullRequest
0 голосов
/ 20 января 2010

Как можно запустить несколько вычислений параллельно, останавливая их все, когда возвращается первое?

Я имею в виду следующее приложение: существует несколько способов вычисления определенного значения;каждый метод занимает разное количество времени в зависимости от параметров функции;при параллельном запуске вычислений каждый раз автоматически "выбираются" самые быстрые вычисления, а другие вычисления останавливаются.

Теперь есть некоторые " детали ", которые задают этот вопросболее сложный:

  • Параметры вычисляемой функции включают в себя функции (которые рассчитываются по точкам данных; они не являются функциями модуля верхнего уровня).Фактически, вычисление - это свертка двух функций.Я не уверен, как такие параметры функции могут быть переданы в подпроцесс (они не могут быть извлечены).
  • У меня нет доступа ко всем кодам вычислений: некоторые вычисления выполняются Scipy изнутри (вероятно, через FortranКод С).Я не уверен, предлагают ли потоки что-то похожее на сигналы завершения, которые могут быть отправлены процессам.

Это то, что Python может сделать относительно легко?

Ответы [ 3 ]

1 голос
/ 20 января 2010

Я бы посмотрел на модуль multiprocessing, если вы еще этого не сделали. Он предлагает способ разгрузки задач для разделения процессов, в то же время предоставляя вам простой threading подобный интерфейс.

Он предоставляет те же виды примитивов, что и в модуле threading, например рабочие пулы и очереди для передачи сообщений между вашими задачами, но позволяет обойти проблему GIL, поскольку ваши задачи на самом деле выполняются в отдельных процессах.

Фактическая семантика того, что вы хотите, довольно специфична, поэтому я не думаю, что есть какая-то рутина, отвечающая всем требованиям, но вы наверняка можете ее выбить.

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

0 голосов
/ 20 января 2010

Процессы можно запускать и убивать тривиально.

Вы можете сделать это.

import subprocess
watch = []
for s in ( "process1.py", "process2.py", "process3.py" ):
    sp = subprocess.Popen( s )
    watch.append( sp )

Теперь вы просто ждете, пока один из них закончится. Когда один закончит, убейте других.

import time
winner= None
while winner is None:
    time.sleep(10)
    for w in watch:
        if w.poll() is not None:
            winner= w
            break
for w in watch:
    if w.poll() is None: w.kill()

Это процессы, а не потоки. Нет GIL соображений. Составьте расписание операционной системы их; это то, что он делает лучше всего.

Далее, каждый процесс - это просто скрипт, который просто решает проблему, используя один из ваших альтернативных алгоритмов. Они полностью независимы и автономны. Простота проектирования, сборки и тестирования.

0 голосов
/ 20 января 2010

Из-за глобальной блокировки интерпретатора вам будет сложно добиться какого-либо ускорения таким образом. В действительности даже многопоточные программы на Python работают только на одном ядре. Таким образом, вы просто выполняете N процессов со скоростью в 1 / N раз больше. Даже если один закончил в два раза быстрее остальных, вы все равно потеряли бы время на общей картине.

...