关于Python multiprocessing.Array创建的共享内存无法删除的问题
2016-09-20 20:26
435 查看
由于GIL(global interpretor lock)机制,Python多线程(multi-thread)操作,不是真正意义上的并行多线程(具体请看这)。因此,Python的并行工作一般采用多进程的方式进行(Multi-process)。多进程相对于多线程最大的问题的数据通信问题,特别是大数组的交换会很慢。
最近项目组在实现Python多线程计算时,采用了pprocess库进行算法的并行。数据交换采用multiprocessing.Array创建数组,传给各个线程用于数据的交换。然而,计算过程中间出现了内存泄漏问题,导致最后内存不够。最后发现是,multiprocessing.Array创建的共享内存无法删除导致。
先上简单测试代码:
我们用mp.Array创建了一个共享内存,用于多进程数据的交换。(由于原因与多进程无关,此处简单化parallel_doSomeWork)使用完毕后,我们将它置为0,“删除”其内存。在一般变量上,这个方法是简单快速有效的。然而,由于mp.Array的特殊性,并没有真正删除,shared memory显示内存依然被占用。
最终解决方法:
将train_data_s=0这一句替换为:
dataheap = train_data_s.get_obj()._wrapper._heap
datastate = train_data_s.get_obj()._wrapper._state
arenaobj = datastate[0][0]
arenaobj.buffer.close()
heap.BufferWrapper._heap = heap.Heap() 长话短说,原因一定是共享内存采用new的方式,在堆区新建了内存,而没有delete。想必multiprocessing一定有其原因。不过既然它本身不主动删,我们又需要删除,那我们就只好自己动手了。亲测300个循环下来并没有什么问题,方法应该是有效的。
如果有大牛知道更好的解决方案,也请不吝指教。
最近项目组在实现Python多线程计算时,采用了pprocess库进行算法的并行。数据交换采用multiprocessing.Array创建数组,传给各个线程用于数据的交换。然而,计算过程中间出现了内存泄漏问题,导致最后内存不够。最后发现是,multiprocessing.Array创建的共享内存无法删除导致。
先上简单测试代码:
import numpy as np import multiprocessing as mp import ctypes import os import time import mmap def parallel_doSomeWork(train_data): train_data[0, 0 ,0] = 1.0 def experiment(n): # creating shared varibale train_data, that can be accessed by multiprocessors train_data_s = mp.Array(ctypes.c_float, 100*n * 64 * 64) train_data = np.frombuffer(train_data_s.get_obj(), dtype=np.float32).reshape(100*n, 64, 64, 1) parallel_doSomeWork(train_data) train_data = 0 train_data_s = 0 def main(): for n in range(1,300): print("loop %d:" % n) # print memory usage info val = os.system("free -m") print val experiment(n) # print memory usage info val = os.system("free -m") print val print() print() if __name__ == '__main__': main()
我们用mp.Array创建了一个共享内存,用于多进程数据的交换。(由于原因与多进程无关,此处简单化parallel_doSomeWork)使用完毕后,我们将它置为0,“删除”其内存。在一般变量上,这个方法是简单快速有效的。然而,由于mp.Array的特殊性,并没有真正删除,shared memory显示内存依然被占用。
最终解决方法:
将train_data_s=0这一句替换为:
dataheap = train_data_s.get_obj()._wrapper._heap
datastate = train_data_s.get_obj()._wrapper._state
arenaobj = datastate[0][0]
arenaobj.buffer.close()
heap.BufferWrapper._heap = heap.Heap() 长话短说,原因一定是共享内存采用new的方式,在堆区新建了内存,而没有delete。想必multiprocessing一定有其原因。不过既然它本身不主动删,我们又需要删除,那我们就只好自己动手了。亲测300个循环下来并没有什么问题,方法应该是有效的。
如果有大牛知道更好的解决方案,也请不吝指教。
相关文章推荐
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于Python multiprocessing.Array创建的共享内存无法删除的问题
- 关于WORD提示“Word无法创建工作文件,请检查临时环境变量”问题的解决办法
- 关于图片在窗体显示后,无法更新或删除的问题
- 关于TFS2010 远程无法创建团队项目的若干问题总结
- 关于登录sql server 2005 出现“已成功与服务器建立连接,但是在登录过程中发生错取。(provider:共享内存提供程序,error:0-管道的另一端上无任何进程”的问题
- linux中共享内存使用过程中奇怪的问题:shmctl删除后其他进程不能再连接该共享内存
- 关于Relay Log无法自动删除的问题
- 在eclipse中误创建了超长的文件夹而引发的“无法删除指定的文件名无效或太长”问题
- 关于CentOS安装无法安装mysql-python组件问题
- 关于在c#中创建用户控件后,winform应用程序在调用中无法通过点击用户控件的子控件为其自动添加事件代码的问题