2015-05-22 78 views
2

這裏是我遇到的問題的玩具示例。我有一個用於大型python腳本的Singleton類。我希望多輸入運行此腳本多次: 的單件模式在這裏沒有必要,但在我的更復雜的實際使用還有一個原因是使用它使用單例類時在多處理中共享的狀態

import time 
import multiprocessing 


class TestClass(object): 
    instance = None 

    @classmethod 
    def get_instance(cls): 
    if cls.instance is None: 
     print 'creating instance' 
     cls.instance = TestClass() 
    return cls.instance 

    def __init__(self): 
    self.data = [] 


def worker(num): 
    tc = TestClass.get_instance() 
    time.sleep(0.1) 
    tc.data.append(num) 
    return tc.data 


def main(): 
    pool = multiprocessing.Pool(processes=1) 
    res = pool.map(worker, range(10)) 

    print res 
    print TestClass.get_instance().data 


main() 

當我運行上面的代碼,它似乎TestClass.instance的狀態是(半 - ?)共享。其結果是:

[[0, 1, 2], [0, 1, 2], [0, 1, 2], ..., [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] 

如果我改變的進程數到10,我得到:

[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]] 

這是結果,我想。

(如果我打電話pool.map()然後後打印TestClass.get_instance().data我得到一個空列表。)

,這是什麼行爲,如何解釋呢? 有沒有辦法阻止這種狀態共享並獲得第二個輸出,但是保持對池中進程數量的控制?

編輯: 當我選擇N個實例來運行M個不同參數的函數。 實例創建N次。理想情況下,我想創建M個實例,每個參數一個。

+0

爲什麼在這裏使用單處理模式進行多處理?這似乎有點多餘,因爲每個子進程都有它自己的解釋器狀態(儘管從父進程派生出來*)。 –

+0

它只是一個玩具的例子,真正的腳本有更多的事情發生,並且這意味着我想使用單身人士出於各種原因 – camz

+0

但是你確實意識到你的例子使用單身人士是沒用的嗎?既然你在每個進程中產生了''TestClass''的多個實例?如果你有''processes = 10'',你將會創建10個「TestClass」實例。 –

回答

1

好的;釋義:

我想創建n個進程運行的M個不同 參數的函數;而不是N個工作進程,我希望M工作人員 進程;每個參數排列一個。

對於multiprocessing.Pool,這不可能,因爲它不是爲此用例而設計的。它更類似於內置函數map(),您可以將函數應用於跨多個工作進程的CPU綁定的輸入序列。

將必須使用multiprocessing.Process()自己管理一組工作進程。

+0

感謝您的解釋。當進程= 1時,我以爲它會創建所有10個進程,但只能同時運行1個進程。但它似乎創建1並使用它10次。 – camz

+0

確實:)謝謝你幫我理解你的問題! –