关于Python multiprocessing.Array创建的共享内存无法删除的问题

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

         如果有大牛知道更好的解决方案,也请不吝指教。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值