2017-08-11 56 views
1

我有几个过程需要一个单一的大numpy的阵列中的每个完成任务,这只是被读取(线程正在寻找它为适当的值)。多处理 - 使用管理者命名空间来保存存储器

如果每个进程加载的数据我收到一个内存错误。

我试图因此通过使用管理器共享的进程之间的同一阵列来最小化存储器的使用。

但是我仍然收到一个内存错误。 I 可以在主进程中加载​​阵列一次,但是当我尝试使其成为属性的管理器名称空间时,我收到一个内存错误。我认为管理者像指针一样行事,并允许独立进程(通常只能访问自己的内存)访问这个共享内存。然而,错误中提到酸洗:

Traceback (most recent call last): 
    File <PATH>, line 63, in <module> 
    ns.pp = something 
    File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\managers.py", line 1021, in __setattr__ 
    return callmethod('__setattr__', (key, value)) 
    File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\managers.py", line 716, in _callmethod 
    conn.send((self._id, methodname, args, kwds)) 
    File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\connection.py", line 206, in send 
    self._send_bytes(ForkingPickler.dumps(obj)) 
    File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\reduction.py", line 50, in dumps 
    cls(buf, protocol).dump(obj) 
MemoryError 

我认为,当分配给经理numpy的阵列实际上是被复制,但我可能是错的。

使事情多一点刺激我32GB内存的机器,看内存使用它只有5%-10%,至多增加了一点berfore崩溃,也许上。

有人能解释为什么使得阵列的命名空间的属性占用更多的内存?为什么我的程序不会使用一些可用的备用内存?(我已阅读,因此namespacemanager文档以及这些managersnamespace线程。

我运行Windows Server 2012 R2和Python 3.5.2 32位。

下面是一些代码演示我问题(你需要使用其他文件large.txt,这个文件是〜制表符分隔字符串75MB):

import multiprocessing 
import numpy as np 

if __name__ == '__main__': 

    # load Price Paid Data and assign to manager 
    mgr = multiprocessing.Manager() 
    ns = mgr.Namespace() 

    ns.data = np.genfromtxt('large.txt') 
    # Alternative proving this work for smaller objects 
    # ns.data = 'Test PP data' 
+0

请参阅[** _是否将共享只读数据复制到不同进程以进行多处理?_ **](https://stackoverflow.com/questions/5549190/is-shared-readonly-data-copied-to-different-processes - 用于多处理)。 – martineau

回答

2

经理类型是灵活性没有效率,他们创建包含值的服务器进程,并且可以将代理对象返回到它们需要的每个进程中。服务器和代理通过tls进行通信以允许服务器和代理位于不同的机器上,但这必然意味着复制所讨论的任何对象。我一直没有追踪源代码,因此可能在使用后多余的副本可能会被垃圾收集,但至少最初必须有副本。

如果你想共享物理内存,我建议使用Shared ctypes Objects。这些实际上确实指向内存中的一个共同位置,因此速度更快,资源更少。它们不支持全胖python对象所做的所有相同的事情,但可以通过创建structs来组织数据来扩展它们。

+0

你建议'结构',但会ctypes阵列也适合? –

+0

什么是tls?并且是否有您的信息的具体来源(除了文档)我可以阅读以了解更多信息? –

+0

@Harrydewinton [来源](https://github.com/python/cpython/blob/master/Lib/multiprocessing/managers.py)永远不会撒谎。tls是[传输层安全](https://en.wikipedia.org/wiki/Transport_Layer_Security)。这是一种通过套接字进行通信的通信协议(可以是进程间的,也可以是通过像以太网这样的物理层进行转发的) – Aaron