2017-06-22 46 views
0

我有一個非常可並行的任務:給定一個ID,在圖結構中查找它,查看它指向的ID並計算它們的值的平均值。Python多處理,將文件作爲深層文件傳遞?

我正在使用python multiprocessing完成此任務,我有一個名爲的對象,它總結了我感興趣的屬性和層次結構。

在一個非常簡單的方式使用Python多:

processes = [] 

for i in range(10): 
    currDataset = getOneTenthofDataset(fullDataset) 
    process = multiprocessing.process(name='name', target=func1, args=(currDataset, graph)) 
    processes.append(process) 
    process.start() 

for p in processes:    
    p.join() 

def func1(dataset, graph): 
    ... 
    for each row of dataset query on graph, update current row accordingly 
    save dataset to file (I don't need to return the splitted datasets!) 

我看到的計算時間幾乎沒有加速(我認爲這可能是由於這樣的事實,查詢在圖形上排隊,而不是正在做並行?) 所以我所做的就是

def func2(dataset, graph): 
    localGraph = copy.deepcopy(graph) 
    .. same code as func1 .. 

這導致了一個神祕而陌生的錯誤!事實上,並非所有的過程都能正確結束,但只有其中的1/3到1/2,並且每次不同的過程都能正確結束。避免深度複製,而不是一切正常。 另一個奇怪的行爲是,沒有到達最後的進程不會拋出任何錯誤,它們只是停止執行,不會繼續執行deepcopy之後的指令! 最後,程序終止沒有任何錯誤

+0

您是在Windows還是類似unix的系統? – tdelaney

+0

Unix:Ubuntu 16.10 – user5609462

回答

0

multiprocessing需要序列化/反序列化您傳遞給函數的任何參數。如果你的數據集很大,那將是很昂貴的。在分叉系統(不是Windows!)上,您可以利用子進程獲取父進程的內存複製視圖並跳過複製的事實。將fullDataset和放在某個地方,func1可以在不作爲參數傳遞的情況下找到它,例如模塊的global名稱空間。由於您的示例代碼已經在模塊級別,因此我假設您已經完成了該操作。將getOneTenthOfDataset替換爲getDatasetSlice(我當然是這樣做的),你很好走。

processes = [] 

for i in range(10): 
    process = multiprocessing.process(name='name', target=func1, args=(i,)) 
    processes.append(process) 
    process.start() 

for p in processes:    
    p.join() 

def func1(i): 
    dataset = getDatasetSlice(i) 
    graph # Its already in module namespace 
    .... 
    for each row of dataset query on graph, update current row accordingly 
    save dataset to file (I don't need to return the splitted datasets!) 
+0

我仍然不明白爲什麼deepcopy失敗,沒有錯誤拋出,但這完全解決了我的問題,很好的知道! – user5609462