2017-05-09 31 views
-1

我有大量的CPU綁定任務,我想並行運行。大多數這些任務將返回類似的結果,我只需要存儲唯一的結果並計算非唯一的結果。使用python multiprocessing.Pool而不返回結果對象

下面是它是如何設計的:我使用兩個託管字典 - 一個用於結果,另一個用於結果計數器。我的任務是使用唯一結果鍵檢查這些字典是否找到了結果,並寫入這兩個字典或只增加非唯一結果的計數器(如果必須寫入,則獲取鎖並再次檢查以避免不一致)。

我擔心的是:因爲Pool.map實際上應該返回結果對象,即使我不保存對它的引用,結果仍然會堆積在內存中,直到它們被垃圾收集爲止。即使我將擁有數百萬的None(因爲我以不同的方式處理結果,而我的所有任務都只返回None),所以我無法依賴特定的垃圾收集器行爲,因此程序最終可能會耗盡內存。我仍然希望保留池的很好的功能,但省去了這個內置的結果處理。我的理解是否正確,是我關心的問題嗎?如果是這樣,有沒有其他的選擇?

此外,現在我把它放在紙上看起來真的很笨拙:)你看到更好的方法來設計這樣的事情嗎?

謝謝!

+0

任何原因,你不能只使用泳池的['apply_async'](HTTPS ://docs.python.org/2/library/multiprocessing.html#multiprocessing.pool.multiprocessing.Pool.apply_async)在一個循環中產生你的進程?如果您在結果回調中將主要進程存儲/放回,則更好。 – Linuxios

+0

我有一個生成器對象爲我的池生成輸入。只有當工作人員免費時,地圖調用纔會要求發電機進行下一次輸入,因此我基本上可以根據需要生成輸入。如果我在循環中使用apply_async,我認爲它會立即爲我的池生成大量待處理任務,這會消耗我所有的內存。或者我錯了? –

+0

啊哈。我想你可能不得不手動做這個。您仍然可以使用多處理來啓動進程並管理進程間通信,但是您可能只需手動編寫處理的子進程,並在完成時向生成器請求一個計算的新值。 – Linuxios

回答

0

問題:我還是要保持池

不錯的功能從multiprocessing.Pool刪除return result

  1. 複製class MapResultmp.pool.ApplyResultinherit
    添加,更換,發表意見如下:

    import multiprocessing as mp 
    from multiprocessing.pool import Pool 
    
    class MapResult(mp.pool.ApplyResult): 
        def __init__(self, cache, chunksize, length, callback, error_callback): 
         super().__init__(cache, callback, error_callback=error_callback) 
         ... 
         #self._value = [None] * length 
         self._value = None 
         ... 
        def _set(self, i, success_result): 
         ... 
         if success: 
          #self._value[i*self._chunksize:(i+1)*self._chunksize] = result 
    
  2. multiprocessing.Pool創建您自己的class myPool(Pool)繼承。
    複製def _map_async(...multiprocessing.Pool
    添加,更換,發表意見如下:

    class myPool(Pool): 
        def __init__(self, processes=1): 
         super().__init__(processes=processes) 
    
        def _map_async(self, func, iterable, mapper, chunksize=None, callback=None, 
          error_callback=None): 
         ... 
         #if self._state != RUN: 
         if self._state != mp.pool.RUN: 
         ... 
         #return result 
    

測試使用Python 3.4.2

+0

按需生成輸入的能力(地圖調用只會在工人變爲空閒時纔會向我的生成器詢問下一個輸入),重用流程,只是在一般情況下使用方便,除了一點小事情和結果。 對不起,我不是故意實現了自己的託管字典,而是使用了OOB。在帖子中編輯了相同的內容。 –

+0

對不起,OOB =開箱即用。只是Manager.dict()從多處理:) –

+0

@TTT:更新我的答案與HowTo從'Pool'中刪除'return result'。 – stovfl