2017-08-11 54 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