您的位置:首页 > 编程语言 > Python开发

关于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创建的共享内存无法删除导致。

         先上简单测试代码:

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个循环下来并没有什么问题,方法应该是有效的。

         如果有大牛知道更好的解决方案,也请不吝指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐