并行运行子进程

时间:2014-05-22 23:13:45

标签: python subprocess

我有一个python脚本,必须调用某个应用程序3次。这些调用应该是parralel,因为它们需要数小时才能完成并且不依赖于彼此。但是他们的脚本应该停止,直到所有这些脚本完成,然后做一些清理工作。

以下是一些代码:

#do some stuff

for work in worklist:   # these should run in parralel
    output=open('test.txt','w')
    subprocess.call(work,stdout=output,stderr=output)
    output.close()

# wait for subprocesses to finish

# cleanup

所以我基本上想在parrelel中运行此命令,同时将其输出捕获到文件中。一旦完成所有实例,我想继续脚本

2 个答案:

答案 0 :(得分:4)

subprocess.call()正在阻止。这意味着,每个调用必须等待子进程完成才能继续。

您想要的是将参数传递给subprocess.Popen构造函数。这样,您的子进程就可以不受阻塞地启动。

稍后,您可以通过致电Popen.communicate()Popen.wait()将这些子流程加入到一起。

child_processes = []
for work, filename in worklist:
    with io.open(filename, mode='wb') as out:
        p = subprocess.Popen(work, stdout=out, stderr=out)
        child_processes.append(p)    # start this one, and immediately return to start another

# now you can join them together
for cp in child_processes:
    cp.wait()                         # this will block on each child process until it exits

P.S。您是否查看了subprocess module上的Python文档?

答案 1 :(得分:1)

我喜欢在这样的情况下使用GNU Parallelhttp://www.gnu.org/software/parallel/)(需要* nix),因为它提供了一种获得并行性的快速方法,并且有很多选项,包括重新组织输出结束,使得它们从每个进程按顺序一起流动但不交错。您还可以指定要一次运行的数字,特定数字或与您拥有的核心数相匹配,它将排队其余命令。

只需使用subprocess.check_outputshell=True一起使用您的命令字符串呼叫parallel。如果你有一个你想要插入的变量,比如你想要运行命令的SQL表的列表,那么并行也很擅长处理它 - 你可以输入一个文本文件的内容与论点。

如果命令完全不同(而不是对同一命令的变体),请将完整的命令放入管道导入parallel的文本文件中。

您也不需要做任何特殊的事情来等待它们完成,因为check_output调用将阻塞,直到parallel命令完成。