Python中的异步后台进程?

11 投票
1 回答
13440 浏览
提问于 2025-04-15 20:43

我一直在参考这个内容,但没能完全实现我需要的功能:在Python中调用外部命令

我还在看这个:http://www.python.org/dev/peps/pep-3145/

对于我们的项目,我们有5个svn检出需要在部署应用程序之前更新。在我的开发环境中,快速部署比生产环境更重要,所以我一直在努力加快这个过程。

我有一个bash脚本,运行得还不错,但也有一些限制。我用以下bash命令同时启动多个'svn update':

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

这些命令都是并行运行的,效果挺好。我在构建脚本的其他部分也用这个模式来启动每个ant构建,然后把生成的war文件移动到Tomcat。

不过,如果其中一个更新或构建失败,我就无法控制停止部署。

所以我正在用Python重写我的bash脚本,这样我可以更好地控制分支和部署过程。

我使用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

不要使用 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'

撰写回答