【发布时间】:2021-02-23 17:44:21
【问题描述】:
我正在尝试在线程池中运行模拟并将每次重复的结果存储在全局 numpy 数组中。但是,我在这样做时遇到了问题,我观察到以下(简化)代码(python 3.7)的一个非常有趣的行为:
import numpy as np
from multiprocessing import Pool, Lock
log_mutex = Lock()
repetition_count = 5
data_array = np.zeros(shape=(repetition_count, 3, 200), dtype=float)
def record_results(repetition_index, data_array, log_mutex):
log_mutex.acquire()
print("Start record {}".format(repetition_index))
# Do some stuff and modify data_array, e.g.:
data_array[repetition_index, 0, 53] = 12.34
print("Finish record {}".format(repetition_index))
log_mutex.release()
def run(repetition_index):
global log_mutex
global data_array
# do some simulation
record_results(repetition_index, data_array, log_mutex)
if __name__ == "__main__":
random.seed()
with Pool(thread_count) as p:
print(p.map(run, range(repetition_count)))
问题是:我得到了正确的“开始记录和完成记录”输出,例如开始记录 1... 结束记录 1。但是,每个线程修改的 numpy 数组的不同切片不会保存在全局变量中。换句话说,线程 1 修改过的元素仍然为零,线程 4 覆盖了数组的不同部分。
补充一点,全局数组的地址,我通过它检索
print(hex(id(data_array))) 对于所有线程都是相同的,在它们的 log_mutex.acquire() ... log_mutex.release() 行内。
我错过了一点吗?就像,每个线程都存储了多个全局 data_array 副本?我正在观察一些这样的行为,但是当我使用 global 关键字时不应该是这种情况,我错了吗?
【问题讨论】:
-
您不是在使用多个线程,而是在使用多个进程。
id只在一个进程中是唯一的
标签: python python-3.x multithreading numpy mutex