2010-08-10 40 views
6

我有一個複雜的數據結構(用戶定義類型),在其上執行大量的獨立計算。數據結構基本上是不可變的。我基本上說,因爲儘管界面看起來不可變,但內部還是有一些懶惰評估正在進行。一些延遲計算的屬性存儲在字典中(通過輸入參數返回昂貴函數的值)。 我想用Pythons multiprocessing模塊來並行化這些計算。我腦海中有兩個問題。在Python中的進程之間共享數據

  1. 如何最好地共享進程之間的數據結構?
  2. 有沒有辦法處理惰性評估問題,而不使用鎖(多個進程寫入相同的值)?

在此先感謝您的任何答案,意見或啓發性問題!

+0

你在說多大/多複雜?當提交「獨立計算」時,您是否知道在開始之前需要哪些惰性屬性? – MattH 2010-08-10 10:24:45

+0

這個問題基本上是對大量數據樣本的一次性交叉驗證。我的機器在單個內核上需要花費大約兩個小時,但我可以使用24個內核的機器,並希望利用此功能。我事先不知道哪一個屬性會被一次計算所需要,但是我知道最終(在所有計算中)所有屬性都將被需要,所以我可以將它們全部加載到前面(但必須測試)。 – 2010-08-10 10:30:17

回答

8

如何最好地共享進程之間的數據結構?

管道。

origin.py | process1.py | process2.py | process3.py 

打破你的程序,使每個計算是一個單獨的下列形式的過程。

def transform1(piece): 
    Some transformation or calculation. 

對於測試,您可以像這樣使用它。

def t1(iterable): 
    for piece in iterable: 
     more_data = transform1(piece) 
     yield NewNamedTuple(piece, more_data) 

要在單個進程中重現整個計算,您可以執行此操作。

for x in t1(t2(t3(the_whole_structure))): 
    print(x) 

你可以用一點文件I/O來包裝每個轉換。 Pickle適用於此,但其他表示(如JSON或YAML)也可以很好地工作。

while True: 
    a_piece = pickle.load(sys.stdin) 
    more_data = transform1(a_piece) 
    pickle.dump(NewNamedTuple(piece, more_data)) 

每個處理步驟成爲一個獨立的OS級進程。它們將同時運行,並立即 - 消耗所有操作系統級資源。

有沒有辦法處理懶惰評估問題,而不使用鎖(多個進程寫入相同的值)?

管道。

+0

哇,這答案解決了兩個問題,即使在我的問題甚至沒有(如何發送複雜的對象到另一個進程,如何在多處理模塊不可用時在python中執行此操作)! – 2010-08-10 10:22:59

+0

關鍵是OS級(共享緩衝區)進程管理(a)更簡單,(b)可以像更復雜的多線程,共享任何技術一樣快。 – 2010-08-10 11:08:06