2016-08-30 51 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代替。

注意:全局通常用厌恶的方式查看...将数组传递给函数。