使用Python subprocess模块并行进程打印输出异常问题
问题排查与解决思路
我来帮你拆解一下这个问题——你的代码确实启动了两个子进程,但只看到test1输出的情况,主要是输出缓冲和等待顺序这两个关键点在搞鬼:
核心原因分析
1. 子进程的输出缓冲机制
Python的print函数默认在终端环境下是行缓冲(打印一行就输出一行),但如果父进程不是在终端中运行(比如IDE、脚本批量执行),子进程的stdout会切换为全缓冲模式:输出内容会先存在内存缓冲区里,攒到足够大的体积才会一次性打印出来。如果test2.py是无限循环打印,它的输出可能一直被卡在缓冲区里,根本没机会显示到控制台。
2. wait()的调用顺序问题
你先调用了p1.wait(),这会让父进程完全阻塞,直到test1.py运行结束。如果test1.py是无限循环(一直打印'test1'),父进程会一直卡在这里,虽然test2.py已经在后台启动运行,但它的输出要么被缓冲,要么因为父进程没处理,你完全看不到它的内容。
解决方法
针对这两个问题,你可以按以下方式修改代码:
方法一:禁用子进程的输出缓冲
启动子进程时给Python加上-u参数,强制Python使用无缓冲的标准输出:
import subprocess # 加上-u参数禁用输出缓冲 p1 = subprocess.Popen(['python', '-u', 'test1.py']) p2 = subprocess.Popen(['python', '-u', 'test2.py']) # 依次等待进程结束(如果是无限循环则会一直运行) p1.wait() p2.wait() print('The main and sub-processes are finished')
方法二:在子进程代码中手动刷新输出
修改test1.py和test2.py的print语句,加上flush=True参数,强制每次打印都立刻刷新缓冲区:
# test1.py 示例代码 import time while True: print('test1', flush=True) time.sleep(0.5)
方法三:同时等待多个子进程(更优雅的方式)
如果你不想因为等待一个进程而阻塞另一个的输出,可以循环等待所有子进程,避免单进程阻塞:
import subprocess p1 = subprocess.Popen(['python', '-u', 'test1.py']) p2 = subprocess.Popen(['python', '-u', 'test2.py']) # 循环等待所有子进程完成,不会单独阻塞某一个 for proc in [p1, p2]: proc.wait() print('The main and sub-processes are finished')
验证效果
修改后再运行父进程,你应该能看到test1和test2的输出交替出现,完全符合你预期的并行运行效果。
内容的提问来源于stack exchange,提问作者utengr
相关产品推荐
相关产品推荐

