2012-03-30 74 views
1

我正在研究工作者的multiprocessing.Pool,試圖用某種狀態初始化工作人員。該池可以進行可調用,初始化,但不會傳遞對已初始化的工作者的引用。我見過的幾個例子利用它調用全局變量,這看起來真的很討厭。在python多處理工作池中初始化的使用

是否有任何好方法使用multiprocessing.Pool初始化工人狀態?

編輯:舉個例子:

我有工人,每個做一些相對昂貴的初始化(綁定到套接字),我不希望有做每一次。我可以手動初始化套接字,然後在分配工作時傳遞它們,但跨進程共享文件描述符非常複雜,如果不是不可能的話。所以我每次想處理請求時都必須初始化和綁定。

+1

我有點不清楚爲什麼你的初始化函數需要對工作者的引用,也許你可以提供一個稍微更具體但最簡單的例子,你正在嘗試做什麼。 – mgilson 2012-03-30 14:11:53

+0

您知道有沒有辦法告訴*哪個* worker將被分配給特定的函數調用?那麼爲什麼不簡單在函數參數中包含該狀態呢? – 2012-03-30 14:16:27

回答

1

從技術上講,正確的做法是將初始化函數的結果作爲參數傳遞給worker所執行的每個函數。

在這種情況下,確實具有全局變量是很好也是安全的,因爲通過構建它們可以使私人對象生活在不同過程的不同領域。

我的一般建議是用一種健全的reentrant編程風格構建函數,並在利用multiprocessing功能時允許全局變量。

保持你的榜樣,下面send功能需要一些背景(在這種情況下,插座):

def send(socket, data): 
    pass # ... your code here 
    return dust 

初始化代碼和由工人執行的基本代碼將依賴於全局變量方便。

socket = None 
def init(address, port): 
    global socket 
    socket = magic(address, port) 

def job(data): 
    global socket 
    assert socket is not None 
    return send(socket, data) 

pool = multithreading.Pool(N, init, [address, port]) 
pool.map(job, ['foo', 'bar', 'baz']) 

通過這種方式它變得簡單而自然地測試它沒有多處理對其進行編碼。您可以將您的全局狀態視爲完全安全的上下文膠囊。

爲了方便起見,請記住multiprocessing不擅長髮送複雜數據(例如回調)。最好的方法是發送簡單的數據(字符串,列表,字典,collections.namedtuple ...),並重新構建工作端的複雜數據結構(使用初始化函數)。