2016-08-30 49 views
1

我有一個numpy數組(矩陣),我想用異步填充計算值。因此,我想要有計算值的矩陣距離,但最後我會收到填充了默認值(-1)的矩陣。我明白,在線程之間共享距離時出現問題,但我無法弄清楚什麼是錯誤的。與多線程共享numpy數組

import numpy as np 
import concurrent.futures 

data = range(1, 10) 
amount = len(data) 
default = -1 
distances = np.full((amount, amount), default, dtype=np.float32) 


def calculate_distance(i, j): 
    global distances 
    if i == j: 
     distances[i][j] = 0 
    else: 
     calculated = data[i] + data[j] #doesn't matter how is this calculated 
     distances[i][j] = calculated 
     distances[j][i] = calculated 


with concurrent.futures.ProcessPoolExecutor() as executor: 
    for i in range(0, amount): 
     for j in range(i, amount): 
      future = executor.submit(calculate_distance, i, j) 
      result = future.result() 

executor.shutdown(True) 
print(distances) 
+0

您正在使用進程,而不是線程。我認爲你使用支持分叉的環境。這意味着你得到的過程有一個「距離」的拷貝(實際上是一般的內存)。當這些進程修改「距離」時,他們修改自己的副本。這是一種簡化,因爲可能涉及寫入時複製,但最終結果是相同的。 –

+0

您可能也有興趣在這個關於只讀共享numpy數組在進程之間使用的Q/A:http://stackoverflow.com/questions/17785275/share-large-read-only-numpy-array-between-multiprocessing -processes。 –

+0

首先,當使用'ProcessPoolExecutor'時,你需要包含'if __name__ =='__main __「'後衛,否則你的代碼將無法在所有平臺上工作。其次,在提交下一個任務之前,您需要等待每個任務完成,這樣任務才能被正確執行。第三,由於全局解釋器鎖定,使用線程通常不會讓您獲得更多的Python代碼處理器時間。 –

回答

0

您正在使用ProcessPoolExecutor。這將分叉執行工作的新流程。這些進程不會共享內存,而是分別獲取distances矩陣的副本。

因此,對其副本的任何更改肯定不會反映在原始過程中。

嘗試使用ThreadPoolExecutor代替。

注意:全局通常用厭惡的方式查看...將數組傳遞給函數。