Асинхронные фоновые процессы в Python? - PullRequest
11 голосов
/ 23 марта 2010

Я использовал это в качестве ссылки, но не смог выполнить именно то, что мне нужно: Вызов внешней команды в Python

Я тоже читал это: http://www.python.org/dev/peps/pep-3145/

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

У меня есть скрипт bash, который работал прилично, но имеет некоторые ограничения. Я запускаю несколько обновлений svn с помощью следующей команды bash:

(svn update /repo1) & (svn update /repo2) & (svn update /repo3) &

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

Однако я не контролирую остановку развертывания в случае сбоя одного из обновлений или сборки.

Я переписываю свой bash-скрипт на Python, чтобы иметь больше контроля над ветвями и процессом развертывания.

Я использую subprocess.call () для запуска команд 'svn update / repo', но каждая из них действует последовательно. Я пытаюсь '(svn update / repo) &', и все они отключаются, но код результата возвращается немедленно. Поэтому у меня нет возможности определить, не сработала ли конкретная команда в асинхронном режиме или нет.

import subprocess

subprocess.call( 'svn update /repo1', shell=True )
subprocess.call( 'svn update /repo2', shell=True )
subprocess.call( 'svn update /repo3', shell=True )

Я бы хотел найти способ заставить Python запускать каждую команду Unix, и в случае сбоя любого из вызовов в любой момент весь сценарий останавливается.

1 Ответ

18 голосов
/ 23 марта 2010

Не используйте shell=True. Излишне будет вызывать оболочку для вызова вашей svn программы, и это даст вам код возврата оболочки вместо svn.

repos = ['/repo1', '/repo2', '/repo3']
# launch 3 async calls:
procs = [subprocess.Popen(['svn', 'update', repo]) for repo in repos]
# wait.
for proc in procs:
    proc.wait()
# check for results:
if any(proc.returncode != 0 for proc in procs):
    print 'Something failed'
...