python multiprocessing -在进程之间共享类字典,进程的后续写入反映到共享内存中

l7wslrjt  于 2022-12-20  发布在  Python
关注(0)|答案(1)|浏览(204)

问题

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

我所尝试的

为了解决这个问题,我知道我必须使用法令()由管理器从python的多处理库中创建,这样它就可以在进程之间共享。它可以处理像整数和字符串这样的简单值。然而,我希望创建的字典可以为我处理更深层次的同步,这样我就可以在字典内部创建一个类,并且这种变化会被反映出来。但多重处理似乎要复杂得多。

示例

下面我提供了一个无法正常工作的示例程序,打印出来的值与在辅助函数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()
ghhkc1vu

ghhkc1vu1#

这是一个"陷阱",会给新手带来很多惊喜。问题是,当您有一个托管字典时,要查看传播的更新,您需要更改一个键或一个键的值。从技术上讲,这里您没有更改值,也就是说,您仍然引用同一个对象示例(输入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(内置数据类型)作为变量名。**

相关问题