Запуск подпроцесса Python - PullRequest
1 голос
/ 27 июня 2011

All

Я прочитал несколько веток о том, как запускать подпроцессы в python, и ни один из них мне не помог. Вероятно, потому, что я не знаю, как правильно их использовать. У меня есть несколько методов, которые я хотел бы запустить одновременно, а не последовательно, и я подумал, что модуль подпроцесса сделает это за меня.

def services():
     services = [method1(),
            method2(),
            method3(),  
            mrthod4(),
            method5()]
     return services

def runAll():
    import subprocess
    for i in services():
        proc = subprocess.call(i,shell=True)

Проблема этого подхода заключается в том, что method1 () запускается, а method2 () не запускается, пока не завершится 1. Я попробовал несколько подходов, включая использование subprocess.Popen [] в моем методе services без удачи. Кто-нибудь может мне помочь, как запустить методы 1-5 одновременно?

Спасибо, Адам

Ответы [ 8 ]

4 голосов
/ 27 июня 2011

В соответствии с документацией Python subprocess.call() ожидает завершения команды.Вы должны напрямую использовать subprocess.Popen объекты, которые дадут вам необходимую гибкость.

1 голос
/ 28 июля 2011

В python 3.2.x модуль одновременных фьючерсов делает такие вещи очень легкими.

1 голос
/ 27 июня 2011

subprocess.call() блоков до завершения процесса.

multiprocessing звучит более подходящим для того, что вы делаете.

например:

from multiprocessing import Process

def f1():
    while True:
        print 'foo'

def f2():
    while True:
        print 'bar'

def f3():
    while True:
        print 'baz'

if __name__ == '__main__':
    for func in (f1, f2, f3):
        Process(target=func).start()
1 голос
/ 27 июня 2011

Сказав method1(), вы вызываете функцию и ожидаете ее возврата.(Это функция, а не метод.)

Если вы просто хотите запустить несколько мощных функций параллельно и собрать их результат, вы можете использовать joblib:

from joblib import Parallel, delayed

functions = [fn1, fn2, fn3, fn4]

results = Parallel(n_jobs=4)(delayed(f)() for f in functions)
1 голос
/ 27 июня 2011

Потоки Python больше соответствуют тому, что вы ищете: http://docs.python.org/library/threading.html или даже многопроцессорный модуль: http://docs.python.org/library/multiprocessing.html#module-multiprocessing.

1 голос
/ 27 июня 2011

Вам необходимо использовать & для их асинхронного выполнения. Вот пример:

 subprocess.call("./foo1&", shell=True)
 subprocess.call("./foo2&", shell=True)

Это похоже на обычную оболочку Unix.

РЕДАКТИРОВАТЬ: Хотя есть несколько, гораздо лучшие способы сделать это. Посмотрите другие ответы для некоторых примеров.

0 голосов
/ 18 марта 2012

У меня недавно была похожая проблема, и я решил ее следующим образом:

from multiprocessing import Pool
def parallelfuncs(funcs, args, results, bad_value = None):
    p = Pool()
    waiters = []
    for f in funcs:
        waiters.append(p.apply_async(f, args, callback = results.append))
    p.close()
    for w in waiters:
        if w.get()[0] == bad_value:
            p.terminate()
    return p

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

w.get блоков, если это не ясно.

В вашем случае вы бы позвонили

results = []
parallelfuncs(services, args, results).join()
print results
0 голосов
/ 27 июня 2011
Подпроцесс

не делает процессы асинхронными.То, чего вы пытаетесь достичь, можно сделать с помощью многопоточного или многопроцессорного модуля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...