Python 2.7下joblib并行执行卡在pd.read_csv无报错问题求助
pandas.read_csv in Multithreaded Parallel Execution (Python 2.7) 我之前遇到过类似的多线程IO阻塞问题,尤其是在Python 2.7这种对线程支持不够完善的老版本里。你的代码卡在pandas.read_csv,且仅在添加多线程并行功能后出现,单线程旧代码正常运行,大概率是IO资源竞争或者Python 2.7的线程GIL与CSV读取的潜在锁冲突导致的,以下是针对性的排查和解决方向:
1. 先验证单线程场景是否正常
先把并行执行的代码注释掉,换成单循环调用,确认每个试验的CSV文件都能正常读取。如果单线程没问题,基本可以锁定是多线程环境下的问题:
# 替换原Parallel代码,先做单线程测试 emd_all_trials = [] for i in range(1, total_trialNum + 1): emd = initialize_container(i) emd_all_trials.append(emd)
2. 修复Python 2.7下pandas.read_csv的线程安全隐患
Python 2.7对应的pandas版本(通常是0.20.x及更早)在多线程读取CSV时,可能存在编码自动检测、日期解析的锁冲突问题。建议:
- 显式指定编码参数,避免自动检测时的线程阻塞
- 禁用日期解析缓存(如果版本支持),减少线程间的资源竞争
修改pupil_data.load_data中的代码:
full_path = filepath + str(trialNum) + ".csv" # 显式指定编码,禁用日期缓存 data = pd.read_csv(full_path, encoding='utf-8', cache_dates=False)
3. 替换为多进程执行(规避GIL影响)
Python的线程受GIL限制,IO密集型任务理论上可并行,但Python 2.7的线程IO处理存在不少坑。换成multiprocessing后端,让每个进程独立处理IO,避免线程间的资源竞争:
emd_all_trials = Parallel(n_jobs=total_trialNum, backend='multiprocessing')( delayed(initialize_container)(i) for i in range(1, total_trialNum + 1) )
注意:用多进程时,subj、u_dim这类全局变量建议改为函数参数传入,避免进程间的变量共享异常。
4. 排查文件路径的隐藏问题
虽然你确认路径无误,但多线程下可能出现拼接时的隐形问题(比如空格、特殊字符)。建议在load_data中打印完整路径,单线程测试时确认所有文件都能正常访问:
full_path = filepath + str(trialNum) + ".csv" print("Loading trial file:", full_path) # 单线程运行时检查路径正确性 data = pd.read_csv(full_path, encoding='utf-8')
5. 限制并发数,避免IO资源耗尽
如果total_trialNum过大,同时打开的文件数可能触发系统文件描述符限制,导致read_csv阻塞。可以先减小并发数测试:
# 根据CPU核心数设置合理的并发数,比如4 emd_all_trials = Parallel(n_jobs=4, backend='threading')( delayed(initialize_container)(i) for i in range(1, total_trialNum + 1) )
最后提一句:Python 2.7已经停止维护多年,很多旧版本库的兼容性问题难以彻底解决,如果条件允许,升级到Python 3.8+会从根本上减少这类问题。
内容的提问来源于stack exchange,提问作者R.Z

