Python multiprocessing Pool执行函数异常,输出混乱问题排查
多进程Pool.map输出混乱,该如何修复?
我尝试用multiprocessing.Pool实现多进程功能,但遇到了输出混乱的问题,以下是我的代码:
# 注:原代码缺少导入语句,这里补充完整 from multiprocessing import Pool def func1(x): print(x) if __name__ == "__main__": myList = ["111","222","333","444"] p = Pool(processes=4) res1 = p.map(func1,myList)
我预期的输出是每个字符串完整显示(顺序可以不固定),比如:
222 111 333 444
但实际得到的输出是:3332 122411 44,内容完全混乱拼接在一起了。请问我哪里操作出错了?
问题原因
这个问题的核心是多个子进程同时向标准输出(stdout)打印内容时,输出缓冲区没有同步。不同进程的打印操作会抢占输出资源,导致各自的输出内容被“截断拼接”,最终出现混乱的结果。
解决方法
你可以通过以下几种方式解决这个问题:
方法1:使用进程锁同步输出
给打印操作加一个全局进程锁,确保同一时间只有一个进程能执行打印操作:
from multiprocessing import Pool, Lock # 定义全局锁 print_lock = Lock() def func1(x): with print_lock: print(x) if __name__ == "__main__": myList = ["111","222","333","444"] p = Pool(processes=4) res1 = p.map(func1,myList)
方法2:让子进程返回结果,主进程统一打印
避免子进程直接打印,而是让函数返回要输出的内容,由主进程统一处理打印,从根源上避免资源竞争:
from multiprocessing import Pool def func1(x): # 子进程只处理逻辑,返回结果 return x if __name__ == "__main__": myList = ["111","222","333","444"] p = Pool(processes=4) res1 = p.map(func1,myList) # 主进程统一打印所有结果 for item in res1: print(item)
注:map方法会返回和输入列表顺序一致的结果,如果想要随机顺序的输出,可以改用imap_unordered方法。
方法3:打印时强制刷新缓冲区
在print函数中添加flush=True参数,强制刷新输出缓冲区,减少内容拼接的概率:
from multiprocessing import Pool def func1(x): print(x, flush=True) if __name__ == "__main__": myList = ["111","222","333","444"] p = Pool(processes=4) res1 = p.map(func1,myList)
这种方式操作简单,但在高并发场景下仍可能出现少量混乱,不如加锁方案可靠。
另外补充:你的原代码缺少from multiprocessing import Pool的导入语句,记得补上,否则会触发NameError哦。
内容的提问来源于stack exchange,提问作者Miky1992




