Python多进程Pool.map传递对象为副本,无法写入Excel Sheet的问题
问题分析
你遇到的核心问题是:multiprocessing.Pool的子进程会复制传入的对象,而非共享引用。xlwt的Workbook和Sheet对象不支持进程间共享,子进程里对Sheet的写入操作只会作用在自己的副本上,主进程里的原Sheet完全没被修改,最后保存自然是空的。
解决方法
最稳妥的方案是让子进程计算出要写入的数据,返回给主进程后统一写入Excel,彻底避免进程间共享状态的问题。
修改后的代码示例
import sys import multiprocessing import xlwt from xlwt import Workbook # 子进程只负责生成要写入的数据,不直接操作Sheet def get_prices_in_range(varss): row = varss[0] col = varss[2] start_day = varss[1] # 返回要写入的位置和数据 return (row, col, start_day) if __name__ == '__main__': pool = multiprocessing.Pool(processes=2) # 创建Excel和Sheet(主进程持有) wb = Workbook() sheet1 = wb.add_sheet("Sheet 1") print(sheet1) # 构造输入参数(不需要传Sheet) inputs = [[x] for x in range(2)] for x in inputs: x.extend([1, 2]) # 去掉sheet1参数 # 子进程返回结果列表 results = pool.map(get_prices_in_range, inputs) # 主进程统一写入Sheet for row, col, value in results: sheet1.write(row, col, value) wb.save("test.xls")
方案优势
- 子进程仅负责计算逻辑,不触碰Excel对象,彻底规避进程间对象复制的问题
- 主进程作为唯一操作Excel的进程,保证数据写入的原子性和正确性
- 符合多进程编程核心原则:用数据传递替代状态共享,减少进程间耦合
原代码失效原因
使用pool.map时,每个子进程都会收到sheet1的独立副本(Windows下是序列化重建,Unix下是fork后的内存拷贝),子进程的sheet.write仅修改自身进程内的副本,主进程的sheet1完全不受影响,最终保存的还是初始状态的Workbook。而直接调用函数时,所有操作都在同一进程内,修改的是同一个Sheet对象,因此能正常写入。
内容的提问来源于stack exchange,提问作者Pernoctador
相关产品推荐
相关产品推荐

