2014-07-03 89 views
6

爲什麼python pickle對象的multiprocessing包要在進程之間傳遞它們,即將不同進程的結果返回給主解釋器進程?這可能是一個令人難以置信的幼稚問題,但爲什麼無法處理A說B處理對象「x在內存中的y點,現在是你的」,而無需執行將對象表示爲字符串所需的操作。爲什麼python多處理pickle對象在進程之間傳遞對象?

+0

進程不允許訪問其他進程的內存。這有明顯的安全原因,但也有可能導致一個進程搞砸並破壞其他一些(可能是關鍵的)進程的內存。 – dano

回答

4

multiprocessing在不同的進程中運行作業。進程擁有自己獨立的內存空間,並且通常不能通過內存共享數據。

要使進程通信,您需要某種渠道。一個可能的渠道將是一個「共享內存段」,這聽起來很像。但使用「序列化」更爲常見。我沒有廣泛地研究過這個問題,但我的猜測是共享內存解決方案過於緊密;序列化允許進程進行通信,而不會讓一個進程在另一個進程中造成錯誤。

當數據集非常大且速度很關鍵時,共享內存段可能是最好的選擇。我能想到的主要例子是視頻幀緩衝區圖像數據(例如,從用戶模式驅動程序傳遞到內核,反之亦然)。

http://en.wikipedia.org/wiki/Shared_memory

http://en.wikipedia.org/wiki/Serialization

Linux和其他* NIX操作系統,提供了通過序列數據共享一個內置的機制:「域套接字」這應該是相當快。

http://en.wikipedia.org/wiki/Unix_domain_socket

由於Python有pickle對於系列化運作良好,multiprocessing使用了。 pickle是一種快速的二進制格式;它通常比XML或JSON等序列化格式更高效。還有其他二進制序列化格式,例如Google Protocol Buffers。

使用序列化的一個好處是:在一臺計算機內共享工作(使用額外的內核)或在多臺計算機之間共享工作(在集羣中使用多臺計算機)大致相同。序列化工作是相同的,網絡套接字像域套接字一樣工作。

編輯:@Mike McKerns在下面的評論中說,multiprocessing有時可以使用共享內存。我做了一次Google搜索,發現了這個很好的討論:Python multiprocessing shared memory

+0

要使用共享內存,'multiprocessing'可以利用'ctypes'庫 - 並且用於在'Pool(4).map(f,x)'中共享'x'。你仍然必須通過'pickle'將'f'傳遞給其他處理器。 –

+0

@MikeMcKerns對此表示感謝。我已經更新了答案以包含更多信息。我不記得'multiprocessing'可以用於共享內存。 (但我應該猜到,有時候數據是巨大的,Python應該能夠應付。) – steveha