之前做数据处理,要对9000*12份grb文件进行分析,因为串行读文件效率太低,打算采用并行的方式,使用python mutilprocess库,使用apply_async()多进程并行读文件。
基本情况:一个grb文件大概50mb左右,在超算上面跑。最开始采用的mutilprocess.pool(multiprocessing.cpu_count()),一次可以开32个进程。文件处理方式不含有任何共享变量,不存在进程间通信。
问题:不管是使用.map_async还是啊apply_async,程序运行大概两三个小时候,从ps -l可以发现主进程状态显示未do_wait或者pipe_wait,子进程都显示为futex_状态,程序无法结束,大概只处理了3000份数据。
分析:网上查到的大部分都是进程通信的问题,和我的情况不符合,偶然翻到一篇文章提到了python多进程资源管理做的不好,我怀疑是每个进程处理完一个文件后,资源没清理完,导致占用的缓存或者内存资源越积越多,最后导致缓存内存被占满,系统自己杀死了某个子进程,导致主进程接收不到该子进程的结束消息,使整个代码卡住。
原多进程部分代码如下:
根据日志文件和ps -l发现程序已知卡在最后两行。
阅读mutilprocess官方文档,发现一个被忽视的参数multiprocessing.pool.
Pool
([processes[, initializer[, initargs[, maxtasksperchild[, context]]]]])
中的maxtasksperchild,可以控制每个进程执行多少次任务后自动销毁。
基于这个思路,将代码修改为:
每个进程执行20次后销毁以释放资源。经测试,代码可以正常运行至结束。问题解决。