
本文旨在介绍如何使用 Python 并发执行多个子进程并高效捕获它们的输出。通过使用 multiprocessing.pool.ThreadPool,我们可以避免阻塞主线程,从而显著提高程序的整体执行效率,尤其是在需要同时运行大量独立子进程的场景下。
在 Python 中,使用 subprocess 模块可以方便地创建和管理子进程。然而,当需要同时启动并等待多个子进程完成时,传统的串行方式可能会导致效率瓶颈。subprocess.Popen 本身是非阻塞的,这意味着启动子进程后会立即返回,但 proc.communicate() 方法会阻塞,直到子进程执行完毕。如果按照串行方式调用 communicate(),实际上子进程的执行顺序是被强制的,无法充分利用多核 CPU 的并行处理能力。
为了解决这个问题,我们可以使用 multiprocessing.pool.ThreadPool 来并发地执行 communicate() 方法,从而实现真正的并行处理。ThreadPool 允许我们将任务分配给一个线程池,由线程池负责调度和执行这些任务。
以下是一个改进后的代码示例:
立即学习“Python免费学习笔记(深入)”;
import subprocess
import logging
from multiprocessing.pool import ThreadPool
log = logging.getLogger(__name__) # 假设已经配置好 logging
def runShowCommands(cmdTable) -> dict:
"""
并发执行 cmdTable 中定义的命令,并返回一个包含命令输出的字典。
"""
procOutput = {} # 用于存储命令输出的字典
procHandles = {}
# 启动所有子进程
for cmd, command in cmdTable.items():
try:
log.debug(f"running subprocess {cmd} -- {command}")
procHandles[cmd] = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) # Add shell=True
except Exception as e:
log.error(f"Error starting subprocess {cmd}: {e}")
procOutput[cmd] = f"Error starting subprocess: {e}" # Store error message to procOutput
continue # Skip to the next command
# 定义处理子进程输出的函数
def handle_proc_stdout(handle):
try:
stdout, stderr = procHandles[handle].communicate(timeout=180)
procOutput[handle] = stdout.decode("utf-8") # 将 stdout 部分转换为文本
log.debug(f"subprocess returned {handle}")
if stderr:
log.error(f"subprocess {handle} stderr: {stderr.decode('utf-8')}")
except subprocess.TimeoutExpired:
log.warning(f"subprocess {handle} timed out")
procHandles[handle].kill()
procOutput[handle] = "Timeout"
except Exception as e:
log.error(f"Error communicating with subprocess {handle}: {e}")
procOutput[handle] = f"Error communicating: {e}" # Store error message to procOutput
# 使用线程池并发执行 communicate
threadpool = ThreadPool()
threadpool.map(handle_proc_stdout, procHandles.keys())
threadpool.close()
threadpool.join()
return procOutput代码解释:
注意事项:
总结:
通过使用 ThreadPool,我们可以显著提高并发执行多个子进程的效率。这种方法特别适用于需要同时运行大量独立子进程的场景,例如并行编译、数据处理等。 务必注意线程安全、资源限制和错误处理,以确保程序的稳定性和可靠性。
以上就是并发执行多个 Python 子进程并捕获输出的优化方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号