如何用Python的subprocess模块维持固定并发数并行运行外部命令
实现固定并发数的外部命令并行执行(Python subprocess)
直接给可运行的代码,核心逻辑是跟踪活跃进程,动态补充新进程以维持指定并发数:
import subprocess import time def run_parallel_commands(total_cmds, max_concurrent, cmd): active_processes = [] submitted = 0 completed = 0 # 循环直到所有命令都提交且所有进程结束 while submitted < total_cmds or active_processes: # 清理已结束的进程 finished_procs = [p for p in active_processes if p.poll() is not None] completed += len(finished_procs) # 从活跃列表中移除已结束的进程 active_processes = [p for p in active_processes if p not in finished_procs] print(f"进度: {completed}/{total_cmds} | 当前活跃进程: {len(active_processes)}") # 启动新进程(还有剩余命令且并发数未满时) while submitted < total_cmds and len(active_processes) < max_concurrent: proc = subprocess.Popen(cmd) active_processes.append(proc) submitted += 1 print(f"启动第{submitted}个任务") # 短暂休眠避免CPU空转 time.sleep(0.1) if __name__ == "__main__": # 示例:启动10个记事本,维持最多3个并发 run_parallel_commands( total_cmds=10, max_concurrent=3, cmd=["notepad.exe"] )
关键逻辑说明
- 进程状态检查:用
proc.poll()判断进程是否结束——返回None表示仍在运行,返回数字(退出码)表示已结束 - 动态维持并发:每次循环先清理已完成的进程,再启动新进程,确保活跃进程数不超过
max_concurrent - 循环终止条件:当所有命令都提交(
submitted == total_cmds)且活跃进程为空时,循环结束
注意事项
- 如果需要捕获命令的输出/错误,可以在
Popen中添加stdout=subprocess.PIPE、stderr=subprocess.PIPE,但要注意用proc.communicate()或线程读取,避免死锁 - 可替换
cmd参数为任意外部命令,比如["ping", "-n", "10", "baidu.com"] time.sleep(0.1)可以根据实际情况调整,缩短间隔会更快响应进程结束,但会增加CPU占用
内容的提问来源于stack exchange,提问作者Digvijay Rawat
相关产品推荐
相关产品推荐

