如何并行运行多个子进程并等待它们在Python中完成

lis*_*987 4 python multiprocessing

我正在尝试将bash脚本迁移到Python.

bash脚本并行运行多个OS命令,然后在恢复之前等待它们完成,即:

command1&

command2&

.

命令与

等待

命令

我想使用Python子进程实现相同的功能.这可能吗?如何在恢复之前等待subprocess.call命令完成?

Mar*_*cny 10

您仍然可以使用Popen具有相同输入参数subprocess.call但更灵活的输入参数.

subprocess.call:完整的函数签名与Popen构造函数的签名相同 - 此函数将所有提供的参数直接传递给该接口.

一个区别是subprocess.call块和等待子进程完成(它构建在上面Popen),Popen而不阻塞,因此允许您并行启动其他进程.

请尝试以下方法:

from subprocess import Popen
commands = ['command1', 'command2']
procs = [ Popen(i) for i in command ]
for p in procs:
   p.wait()
Run Code Online (Sandbox Code Playgroud)

  • 我已经测试过,它们可以并行运行。您可以将.wait()替换为.communicate(),并在`Popen()`中添加参数`stdout = subprocess.PIPE和`stderr = subprocess.PIPE`到`Popen()`中。子进程,而不是让它们与父进程的stdout / stderr聚集在一起 (3认同)
  • 在你的代码中,command1 和 command2 同时执行?或者command2在command1完成后启动? (2认同)
  • 它们确实并行运行,因为子进程在 Popen 返回时启动。但它们在 wait() 处阻塞。所以这段代码的作用是,在 procs 数组中循环一次,并在第一个 wait() 处阻塞,直到结束。如果子进程仍在运行,则在下一个 wait() 处阻塞。 (2认同)

Noa*_*man 5

扩展 Aaron 和 Martin 的答案,这是一个运行 usesubprocessPopen并行运行n 个进程的解决方案:

import subprocess
commands = ['cmd1', 'cmd2', 'cmd3', 'cmd4', 'cmd5'] 
n = 2 #the number of parallel processes you want
for j in range(max(int(len(commands)/n), 1)):
    procs = [subprocess.Popen(i, shell=True) for i in commands[j*n: min((j+1)*n, len(commands))] ]
    for p in procs:
        p.wait()
Run Code Online (Sandbox Code Playgroud)

我发现当使用多处理等工具可能导致不良行为时,这非常有用。