python+multiprocess+theano+pylucene--内存泄露解决方案

来源:互联网 发布:富春山居图有多烂 知乎 编辑:程序博客网 时间:2024/06/05 16:05

最近上的项目有TPS要求,串行代码不满足当前需求,需要改成多线程,就查了下Python的多线程,不查不知道,一查吓一跳.

第一,Python是一种动态语言,我的理解是,运行到某一行的时候,才是知道编译成机器码,而不行C、JAVA等 静态语言那样事先编译好再运行,这有一个显著的问题:运行效率低

第二,Python有一个GIL,全称,全局解释器锁,为了解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁,就是因为这个超级大锁的存在,某一个线程运行的时候,其他线程处于阻塞状态,这将严重影响多线程执行效率,甚至可以认为Python就是个单线程的程序。有时候用多线程的解决方案甚至比串行代码还要慢。

第三,引入多线程之后,安装的pylucene报错:RuntimeError: attachCurrentThread() must be called first,大致意思是在启动线程时候没绑定线程,解决办法如下:

vm_env = lucene.initVM(vmargs=['-Djava.awt.headless=true'])#启动Lucene的时候添加vm_env.attachCurrentThread()#绑定线程vm_env.detachCurrentThread()#销毁线程
没发现问题,当压力测试的时候,处理速度确实提升上去了,但发现一个问题:内存使用量只涨不消,运行4mins,程序崩溃,一步步查找问题,一开始就认为是pylucene的原因,于是,通过gdb的方式,查找问题,

sudo gdb python -p PIDS 

绑定程序线程

info threads

发现程序中有很多 xx_xx_xxwait@@XX 函数,这说明有锁的情况存在,当程序完全跑完的时候,反馈,JVM的致命错误日志(hs_err_pid.log)文件,解读发现一句:

# Problematic frame: # C  [_lucene.so+0x12ef5e2]  JCCEnv::callObjectMethod(_jobject*, _jmethodID*, ...) const+0xa2 
C:本地底层C错误,这更加印证了我们的猜想。这一次,我们将,代码中,pyLucene代码接口写死,测试发现,代码内存基本保持不变,说明pylucene本身存在thread-safe问题,通过直接访问知识图谱库,验证实体。

第四,修改好之后,再测代码,再次发现问题:

 python2.7: /root/.theano/compiledir_Linux-4.10--generic-x86_64-with-Ubuntu-16.04-xenial-x86_64-2.7.12-64/tmphR0K8Y/mod.cpp:122: int {anonymous}::__struct_compiled_op_1b3927e45c5a4a2e8fa7da824d41d6af::run(): Assertion `PyArray_NDIM(V5) == 1' failed. 
一查,发现,Theano is not thread-safe,
 Theano Error with Ubuntu 14.04: Assertion `PyArray_NDIM(V5) == 1' failed. #3735 ,Theano owner 给的意见是 考虑进程而不是线程。解决方案进而转向tensorflow。


原创粉丝点击