Python 并行运行子进程

Python 并行运行子进程,python,subprocess,Python,Subprocess,我有一个python脚本,它必须调用某个应用程序3次。这些呼叫应该是并行的,因为它们需要几个小时才能完成,并且彼此不依赖。但他们应该停止编写脚本,直到所有脚本都完成,然后进行一些清理工作 下面是一些代码: #do some stuff for work in worklist: # these should run in parralel output=open('test.txt','w') subprocess.call(work,stdout=output,stder

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

下面是一些代码:

#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中运行这个命令,同时将其输出捕获到一个文件中。完成所有实例后,我希望继续脚本

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

您需要的是将参数传递给
subprocess.Popen
构造函数。这样,您的子进程将在不阻塞的情况下启动

稍后,您可以通过调用
Popen.communicate()
Popen.wait()
将这些子进程连接在一起


顺便问一下,您有没有查阅过Python在上的文档

我喜欢在这种情况下(需要*nix)使用
GNU Parallel
(),因为它提供了一种快速获得并行性的方法,并且有许多选项,包括在最后重新组织输出,使其按顺序从每个进程流到一起,而不是交错。您还可以指定要一次运行的数量,或者指定一个特定的数量,或者指定与您拥有的内核数量相匹配的数量,它将对其余命令进行排队

只需使用
subprocess。使用
shell=True检查\u output
,即可使用命令字符串调用
parallel
。如果您有一个要插入的变量,比如一个要运行命令的
SQL
表列表,parallel也很擅长处理这个问题——您可以使用参数插入文本文件的内容

如果命令完全不同(而不是同一命令的变体),请将完整的命令放在文本文件中,然后导入到
parallel


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

如果在for循环调用communicate()之前,其stdout/stderr管道填满,则以后的进程可能会暂停。一个简单的解决方案是通过管道将stdout/err连接到临时文件。我可以直接将stdout和stderror链接到文件句柄吗?stdout=filehandle?也应该是out,err=cp.communicate()?它们确实可以设置为现有的文件句柄。如果我将它们直接路由到文本文件,我将如何等待进程完成?@prgmjunkie,是的
stdout=open('my-process-out.txt','w')
works.related:,.
shell=True
几乎在任何上下文中都是不安全的。确实存在,但也确实存在这样的情况。e、 g.输入不是来自外部网络等的任意来源。
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