使用multiprocessing.Manager字典时出现KeyError: 'train'的解决方法
你的代码尝试用多进程并行预处理训练和测试数据,但运行时出现了KeyError: 'train',说明训练进程没有成功往Manager字典里写入"train"键。下面一步步分析原因并给出解决方案:
你的代码与错误信息
代码片段:
print("Preprocessing data...") with multiprocessing.Manager() as manager: results = manager.dict() preprocess_training = Process(target=preprocess, args=( results, "data\\train.csv", False, "train", min_occurrences, train_data_file_name,)) preprocess_testing = Process(target=preprocess, args=( results, "data\\test.csv", True, "test", min_occurrences, test_data_file_name,)) preprocess_training.start() preprocess_testing.start() print("Multiple processes started...") preprocess_testing.join() print("Preprocessed testing data...") preprocess_training.join() print("Preprocessed training data...") training_data = results["train"] testing_data = results["test"] print("Data preprocessed & cached...")
错误信息:
File "C:\Users\Samad\Anaconda3\lib\multiprocessing\managers.py", line 772, in _callmethod raise convert_to_error(kind, result)
KeyError: 'train'
可能的原因与解决步骤
1. 核心检查:preprocess函数是否正确写入"train"键
这是最常见的问题——你的preprocess函数可能没执行到results["train"] = ...这一步,或者中途抛出异常导致进程提前退出,根本没完成数据写入。
解决方法:
- 给
preprocess函数添加异常捕获,把错误信息存入Manager字典,方便排查进程内部问题:def preprocess(results, csv_path, is_test, data_type, min_occurrences, output_file): try: # 你的原有预处理逻辑(读取CSV、数据清洗等) # ... # 确保最后执行写入操作 results[data_type] = processed_data except Exception as e: # 把错误信息存入字典,便于调试 results[f"{data_type}_error"] = str(e) # 可选:重新抛出异常,让父进程感知到错误 raise - 在进程join后先打印整个results字典,确认里面的键:
preprocess_training.join() preprocess_testing.join() # 先打印字典内容,排查问题 print("Debug: Results dict contains:", dict(results)) training_data = results["train"]
2. 验证文件路径是否正确
Windows下路径用\\时要注意转义问题,建议改用raw字符串(比如r"data\train.csv")。如果data\train.csv不存在,preprocess函数读取文件时会报错,导致无法写入"train"键。
解决方法:
单独测试preprocess函数,传入训练数据路径,确认能正常读取和处理数据,排除文件本身的问题。
3. 处理Windows多进程的特殊要求
Windows系统下Python多进程采用spawn模式,要求主代码必须放在if __name__ == "__main__":块中,否则会重复初始化进程,导致preprocess函数无法正确执行。
解决方法:
把主逻辑包裹在这个判断块里:
import multiprocessing from multiprocessing import Process def preprocess(results, csv_path, is_test, data_type, min_occurrences, output_file): # 你的预处理函数逻辑 pass if __name__ == "__main__": # 这里放你原来的主代码 print("Preprocessing data...") with multiprocessing.Manager() as manager: results = manager.dict() # ... 后续创建进程、启动、join等代码
4. 检查进程是否正常结束
进程可能因内存不足、资源限制等原因被终止,导致未完成写入。可以通过退出码判断:
preprocess_training.join() print("Training process exit code:", preprocess_training.exitcode) preprocess_testing.join() print("Testing process exit code:", preprocess_testing.exitcode)
如果退出码不为0,说明进程异常终止,需要进一步排查原因。
总结
先从preprocess函数的写入逻辑和异常情况入手,再验证文件路径和Windows多进程的代码结构,基本就能定位并解决这个KeyError问题。
内容的提问来源于stack exchange,提问作者Abdul Samad

