2015-11-20 108 views
0

我有一個函數,沒有多處理循環與三元組數組並進行一些計算。這個數組可能真的很長(> 1百萬條目),所以我認爲使用多個進程可以幫助加快速度。死鎖與多處理模塊

我從一列點(random_points)開始,用它創建所有可能的三元組的排列(combList)。這combList然後傳遞給我的功能。 我有基本代碼的作品,但只有當random_points列表有18個條目或更少。

from scipy import stats 
import itertools 
import multiprocessing as mp 

def calc3PointsList(points,output): 
    xy = [] 
    r = [] 
    for point in points: 
    // do stuff with points and append results to xy and r 
    output.put((xy, r)) 


output = mp.Queue() 

random_points = [ (np.array((stats.uniform(-0.5,1).rvs(),stats.uniform(-0.5,1).rvs()))) for _ in range(18)] 
combList = list(itertools.combinations(random_points, 3)) 
N = 6 
processes = [mp.Process(target=calc3PointsList, args=(combList[(i-1)*len(combList)/(N-1):i*len(combList)/(N-1)],output)) for i in range(1,N)] 

for p in processes: 
    p.start() 
for p in processes: 
    p.join() 
results = [output.get() for p in processes] 

只要random_points列表的長度超過18,程序就會進入死鎖狀態。 18和更低,它完成罰款。我是否以錯誤的方式使用整個多處理模塊?

+0

您是否看到N = 4或N = 2的相同問題?對於你的最後一行,我認爲它應該是'results = [output.get for x in range(output.qsize())]' – user3667217

+0

是的,仍然掛着N = 2或N = 4,這意味着1或2個作業我在(1,N)範圍內創建了作業,所以N是排他性的。如果我嘗試了N = 3或N = 5(因此有2或4個作業),如果你的意思是它與作業數量相關,它也會掛起。 感謝提示結果行 – Philipp

回答

0

OK,這個問題是由user2667217提到programming guideline描述:

記住,已經將商品放入隊列中的進程將終止前,直到所有的緩衝項美聯儲等待

熊通過「進料器」螺紋到下面的管道。 (子進程可以調用隊列的Queue.cancel_join_thread方法來避免這種行爲。)

這意味着,無論何時使用隊列,都需要確保放入隊列的所有項最終都會在進程加入之前刪除。否則,您無法確定將項目放入隊列的進程將終止。還要記住,非守護進程會自動加入。

刪除聯接操作使其工作。此外,檢索過程的正確方法似乎如下:

results = [output.get() for p in processes] 
1

我確實看到您發佈的任何其他內容顯然是錯誤的,但您肯定應該做一件事:在if __name__=="main":區塊中啓動新進程,請參見programming guideline

from scipy import stats 
import itertools 
import multiprocessing as mp 

def calc3PointsList(points,output): 
    xy = [] 
    r = [] 
    for point in points: 
    // do stuff with points and append results to xy and r 
    output.put((xy, r)) 

if __name__ == "__main__": 
    output = mp.Queue() 
    random_points = [ (np.array((stats.uniform(-0.5,1).rvs(),stats.uniform(-0.5,1).rvs()))) for _ in range(18)] 
    combList = list(itertools.combinations(random_points, 3)) 
    N = 6 
    processes = [mp.Process(target=calc3PointsList, args=(combList[(i-1)*len(combList)/(N-1):i*len(combList)/(N-1)],output)) for i in range(1,N)] 

    for p in processes: 
     p.start() 
    for p in processes: 
     p.join() 
    results = [output.get for x in range(output.qsize())] 
+0

我假設你的意思是'if name =='__ main __''。我加了這個謝謝,但不管如何,問題仍然存在。 – Philipp