如何在 Python 中共享对象数组



我有一个函数,可以在其中创建进程pool。此外,我还使用multiprocessing.Value()multiprocessing.Lock()来管理进程之间的一些共享值。

我想对对象数组做同样的事情,以便在进程之间共享它,但我不知道该怎么做。我只会从该数组中读取。

这是函数:

from multiprocessing import Value,Pool,Lock,cpu_count
def predict(matches_path, unknown_path, files_path, imtodetect_path, num_query_photos, use_top3, uid, workbook, excel_file_path,modelspath,email_address):

shared_correct_matched_imgs = Value('i', 0)
shared_unknown_matched_imgs = Value('i', 0)
shared_tot_imgs = Value('i', 0)
counter = Value('i', 0)
shared_lock = Lock()
num_workers = cpu_count()

feature = load_feature(modelspath)

pool = Pool(initializer=init_globals,
initargs=[counter, shared_tot_imgs, shared_correct_matched_imgs, shared_unknown_matched_imgs,
shared_lock], processes=num_workers)

for img in glob.glob(os.path.join(imtodetect_path, '*g')):
pool.apply_async(predict_single_img, (img,imtodetect_path,excel_file_path,files_path,use_top3,uid,matches_path,unknown_path,num_query_photos,index,modelspath))
index+=increment

pool.close()
pool.join()

数组是使用指令feature = load_feature(modelspath)创建的。这是我想要共享的数组。

init_globals中,我将共享价值初始化:

def init_globals(counter, shared_tot_imgs, shared_correct_matched_imgs, shared_unknown_matched_imgs, shared_lock):
global cnt, tot_imgs, correct_matched_imgs, unknown_matched_imgs, lock
cnt = counter
tot_imgs = shared_tot_imgs
correct_matched_imgs = shared_correct_matched_imgs
unknown_matched_imgs = shared_unknown_matched_imgs
lock = shared_lock

提供共享静态数据的简单方法是使其成为要调用的函数可访问的全局变量。如果您使用的是支持"fork"的操作系统,那么在子进程中使用全局变量非常简单,只要它们是常量(如果您修改它们,更改将不会反映在其他进程中)

import multiprocessing as mp
from random import randint
shared = ['some', 'shared', 'data', f'{randint(0,1e6)}']
def foo():
print(' '.join(shared))
if __name__ == "__main__":
mp.set_start_method("fork")
#defining "shared" here would be valid also
p = mp.Process(target=foo)
p.start()
p.join()

print(' '.join(shared)) #same random number means "shared" is same object

当使用"spawn"作为启动方法(Windows上唯一可用的方法)时,这将不起作用,因为父级的内存不以任何方式与子级共享,因此子级必须"导入"主文件才能访问目标函数(这也是为什么您可能会遇到装饰器问题的原因。如果您在if __name__ == "__main__":块之外定义数据,它将有点工作,但您将制作数据的单独副本,如果数据很大、创建速度慢或每次创建时都会更改,则可能是不可取的。

import multiprocessing as mp
from random import randint
shared = ['some', 'shared', 'data', f'{randint(0,1e6)}']
def foo():
print(' '.join(shared))
if __name__ == "__main__":
mp.set_start_method("spawn")
p = mp.Process(target=foo)
p.start()
p.join()

print(' '.join(shared)) #different number means different copy of "shared" (1 a million chance of being same i guess...)

相关内容

  • 没有找到相关文章

最新更新