Python多进程处理JSON文件时停滞并触发RuntimeError问题排查
问题与解决方法
问题情况
编写Python多进程代码批量处理JSON文件,目标是提取每个文件中的len字段并写入对应TXT文件,但程序运行停滞无响应,哪怕只处理50个文件(总计3000个)也无法正常工作。用VS Code调试时触发RuntimeError,提示需在主模块中使用if __name__ == '__main__'的正确写法,否则会在进程引导阶段前启动新进程。
原代码:
import multiprocessing import glob import json def handle_json(file): with open(file, 'r', encoding = 'utf-8') as inp, open(file.replace('.json','.txt'), 'a', encoding = 'utf-8', newline = '') as out: length = json.load(inp).get('len','') #Note: each json file is not large and well formed out.write(f'{file}\t{length}\n') p = multiprocessing.Pool(4) for f, file in enumerate(glob.glob("Folder\\*.json")): p.apply_async(handle_json, file) print(f) p.close() p.join() # Wait for all child processes to close.
错误原因
- 缺少主模块保护:Windows系统下,多进程启动时会重新导入主模块,没有
if __name__ == '__main__'的话,会重复执行创建进程池的代码,引发进程启动错误。 - 传参格式错误:
apply_async的第二个参数需要是元组,直接传file会被拆分成单个字符作为参数传递给handle_json,导致函数参数不匹配,程序卡住。
修正后的代码
import multiprocessing import glob import json def handle_json(file): with open(file, 'r', encoding='utf-8') as inp, open(file.replace('.json', '.txt'), 'a', encoding='utf-8', newline='') as out: length = json.load(inp).get('len', '') out.write(f'{file}\t{length}\n') if __name__ == '__main__': p = multiprocessing.Pool(4) for idx, file in enumerate(glob.glob("Folder\\*.json")): # 单个参数需用带逗号的元组传递 p.apply_async(handle_json, (file,)) print(idx) p.close() p.join()
额外优化建议
如果不需要实时打印处理索引,可改用map方法简化代码,无需手动循环:
if __name__ == '__main__': with multiprocessing.Pool(4) as p: p.map(handle_json, glob.glob("Folder\\*.json"))
使用with语句可自动管理进程池的关闭与等待,代码更简洁安全。
内容的提问来源于stack exchange,提问作者Khaled
相关产品推荐
相关产品推荐

