【问题标题】:Python Popen processes without communicate finish quicker没有通信的 Python Popen 进程完成得更快
【发布时间】:2014-01-10 05:21:32
【问题描述】:

我不完全确定为什么,但我本质上想运行 2 个进程,所以我使用子进程 Popen 函数。

commands = ['command 1', 'command 2']
for command in commands:
    proc = Popen(command.split(' '))
    proc.communicate()       # line of interest

这些命令是渲染过程,因此当它们完成时,它们会在目录中创建一个图像。但奇怪的是,当我使用communicate() 运行它们时,基本上是串联的,它们在预期的时间内完成(大致时间1 + 时间2)。

但是,当我在没有通信()的情况下运行它们时,应该有效地并行运行它们,它们需要更长的时间才能完成。有谁知道为什么会发生这种行为以及如何补救?

【问题讨论】:

  • 只有 2 个命令还是您实际上有更多命令?当你运行它时,你的系统资源是什么样的——例如您确定您没有使用内存或其他东西进行交换吗?
  • 是的,实际上只有 2 个(渲染作业,高度并行)。它没有最大化 CPU,也没有使用任何交换空间。资源似乎绰绰有余

标签: python subprocess multiprocessing


【解决方案1】:

要让它们并行运行,您需要多次实例化Popen。您的示例表明您不通过 stdin、stdout 或 stderr 与进程通信,而是通过文件。假设这一点,您可以使用wait 方法而不是communicate。所以结果可能是这样的:

commands = [['command', '1'], ['command', '2']]
processes = [Popen(command) for command in commands]
# they are both running now
returncodes = [process.wait() for process in processes]
# successful if all returncodes are 0

如果您的渲染过程也是用 Python 编写的,请查看 multiprocessing 模块。它可以帮助您使用多个进程并行化您的代码,从而避免 GIL 争用。

如果您确实在与您的进程进行通信,则需要使用更复杂的机制来多路复用 IO 操作。这也是multiprocessing 模块可以派上用场的地方,但您也可以使用asyncore 或其他IO 框架来实现通信。

【讨论】:

    猜你喜欢
    • 2021-06-29
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2015-04-04
    • 2018-12-05
    相关资源
    最近更新 更多