python多处理-在进程之间共享一个类字典,并将进程中的后续写入反映到共享内存中



问题

我需要在进程之间共享一个字典,该字典包含键值对的值组件内部的类实例。使用管理器类中的multiprocessing的dict()创建的字典能够存储值,但随后更新值的写入不会反映到共享内存中。

我尝试过的

为了解决这个问题,我知道我必须使用管理器从python的多处理库中创建的dict(),以便在进程之间共享。这适用于像整数和字符串这样的简单值。然而,我曾希望创建的字典能为我处理更深层次的同步,这样我就可以在字典中创建一个类,这种变化就会得到反映,但多处理似乎比这复杂得多。

示例

下面我提供了一个无法按预期工作的示例程序。打印的值不是在辅助函数f()中设置的值。

注意:我在这个例子中使用了python3

from multiprocessing import Manager
import multiprocessing as mp
import random

class ExampleClass:
def __init__(self, stringVar):
# these variables aren't saved across processes?
self.stringVar = stringVar
self.count = 0

class ProcessContainer(object):
processes = []
def __init__(self, *args, **kwargs):
manager = Manager()
self.dict = manager.dict()
def f(self, dict):
# generate a random index to add the class to
index = str(random.randint(0, 100))
# create a new class at that index
dict[index] = ExampleClass(str(random.randint(100, 200)))
# this is the problem, it doesn't share the updated variables in the dictionary between the processes <----------------------
# attempt to change the created variables
dict[index].count += 1
dict[index].stringVar = "yeAH"
# print what's inside
for x in dict.values():
print(x.count, x.stringVar)
def Run(self):
# create the processes
for str in range(3):
p = mp.Process(target=self.f, args=(self.dict,))
self.processes.append(p)
# start the processes
[proc.start() for proc in self.processes]
# wait for the processes to finish
[proc.join() for proc in self.processes]

if __name__ == '__main__':
test = ProcessContainer()
test.Run()

这是一个"明白了";这给外行带来了很多惊喜。问题是,当您有一个托管字典时,要查看传播的更新,您需要更改键或键的值。在这里,从技术上讲,您没有更改值,也就是说,您仍然在引用同一个对象实例(类型ExampleClass),并且只是在该引用中更改。奇怪,我知道。这是您需要的修改后的方法f

def f(self, dict):
# generate a random index to add the class to
index = str(random.randint(0, 100))
# create a new class at that index
dict[index] = ExampleClass(str(random.randint(100, 200)))
# this is the problem, it doesn't share the updated variables in the dictionary between the processes <----------------------
# attempt to change the created variables
ec = dict[index]
ec.count += 1
ec.stringVar = "yeAH"
dict[index] = ec # show new reference
# print what's inside
for x in dict.values():
print(x.count, x.stringVar)

注意:

如果您使用以下代码来设置密钥/对值,那么以下代码实际上会打印False:

ec = ExampleClass(str(random.randint(100, 200)))
dict[index] = ec
print(dict[index] is ec)

这就是为什么在修改后的方法f中,dict[index] = ec # show new reference看起来是被设置为值的新引用。

此外,您应该考虑不使用dict(一种内置数据类型)作为变量名

相关内容

  • 没有找到相关文章

最新更新