Python 2.7多进程Pool模式下文件写入问题求助
嗨,我之前也踩过这个多进程写文件的坑!多个子进程同时往同一个文件写内容,很容易出现内容乱序、重叠甚至丢失的情况,因为进程之间的文件操作没有同步机制。咱们来看看几种靠谱的解决办法:
1. 使用进程锁(Lock)实现同步写入
这是最直接的方案,通过锁保证同一时间只有一个进程能操作文件。注意要使用Manager创建的锁,因为普通的Lock无法在进程池的子进程间共享:
from multiprocessing import Pool, Manager def f(x, lock): # 用with语句自动管理锁的获取和释放,不用手动调用acquire/release with lock: # 每个进程单独打开文件(用追加模式避免覆盖) with open('test.txt', 'a') as fout_: fout_.write(str(x) + "\n") if __name__ == '__main__': manager = Manager() lock = manager.Lock() p = Pool(5) # 用starmap传递多个参数(x和锁) p.starmap(f, [(num, lock) for num in [1, 2, 3, 4, 5]]) p.close() p.join()
这种方法适合写入操作不频繁的场景,缺点是当进程多的时候,会有锁等待的开销。
2. 每个进程写临时文件,最后合并
如果你的计算任务很重、写入频率高,用锁会拖慢速度,那可以让每个进程写自己的临时文件,最后由主进程统一合并:
from multiprocessing import Pool import os import glob def f(x): # 用进程ID命名临时文件,避免冲突 temp_filename = f'temp_{os.getpid()}.txt' with open(temp_filename, 'a') as fout_: fout_.write(str(x) + "\n") return temp_filename if __name__ == '__main__': p = Pool(5) # 收集所有临时文件的路径 temp_files = p.map(f, [1, 2, 3, 4, 5]) p.close() p.join() # 合并临时文件到最终输出 with open('test.txt', 'w') as final_file: for temp_file in temp_files: with open(temp_file, 'r') as f: final_file.write(f.read()) # 用完就删掉临时文件 os.remove(temp_file)
这种方式完全没有进程间的竞争,效率更高,还能避免锁带来的性能损耗。
3. 主进程统一负责写入
如果计算结果的数据量不大,还可以让子进程只做计算,把结果返回给主进程,由主进程单独写入文件——这是最安全的方案,完全不会有文件竞争问题:
from multiprocessing import Pool def compute(x): # 子进程只专注计算,返回结果字符串 return str(x) + "\n" if __name__ == '__main__': p = Pool(5) # 收集所有计算结果 results = p.map(compute, [1, 2, 3, 4, 5]) p.close() p.join() # 主进程一次性写入所有结果 with open('test.txt', 'w') as fout_: fout_.writelines(results)
另外还要提一句:你原来的代码里在主进程打开文件,然后子进程直接用这个文件对象,这是非常不安全的!文件句柄在多进程间共享会导致不可预测的行为,每个进程应该独立打开/关闭文件,或者用上面的同步方案。
内容的提问来源于stack exchange,提问作者Tim D
相关产品推荐
相关产品推荐

