我有一个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中运行此命令,同时将其输出捕获到文件中。一旦完成所有实例,我想继续脚本
答案 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 Parallel
(http://www.gnu.org/software/parallel/)(需要* nix),因为它提供了一种获得并行性的快速方法,并且有很多选项,包括重新组织输出结束,使得它们从每个进程按顺序一起流动但不交错。您还可以指定要一次运行的数字,特定数字或与您拥有的核心数相匹配,它将排队其余命令。
只需使用subprocess.check_output
与shell=True
一起使用您的命令字符串呼叫parallel
。如果你有一个你想要插入的变量,比如你想要运行命令的SQL
表的列表,那么并行也很擅长处理它 - 你可以输入一个文本文件的内容与论点。
如果命令完全不同(而不是对同一命令的变体),请将完整的命令放入管道导入parallel
的文本文件中。
您也不需要做任何特殊的事情来等待它们完成,因为check_output
调用将阻塞,直到parallel
命令完成。