Python多处理 - 修改共享字典中的值

时间:2017-08-24 19:52:45

标签: python dictionary python-multiprocessing

我正在开发一个项目,我将数据从一个进程解析为python字典,然后由另一个python进程读取,该进程会创建不同的数据视图。解析的数据来自worker1进程处理的传感器。

我到目前为止,我可以使用共享字典创建两个进程,最后我可以毫无问题地添加值。但是,当我想要修改现有值时,我碰到了一堵砖墙。我已经阅读了几个小时的“很多”答案,并尝试了创建包含密钥的新对象的解决方案。例如。 x = d [“key”] [1]; x ='newvalue'。只是不起作用。我在python 3.6中运行代码,但问题在2.7中似乎相似。以下是简化版中的代码:

#!/usr/bin/python3
import subprocess,time
from multiprocessing import Process, Manager

def worker1(d):
    d["key"] = []    #Creating empty dict item
    d["key"]+=["hellostack"] #Adding first value
    d["key"]+=[1]    #Adding second value
    print ("from worker1:",d)
    d["key"][1]+=2 #<<<< ISSUE HERE - Modifying second value does nothing
    print ("Now value should be upped!..",d)

def worker2(d):
    while True:
        time.sleep(1)
        print ("from worker 2:",d)

manager = Manager()
d = manager.dict()

worker1 = Process(target=worker1, args=(d,))
worker2 = Process(target=worker2, args=(d,))
worker1.start()
worker2.start()
worker1.join()
worker2.join()

我得到的输出是:

from worker1: {'key': ['hellostack', 1]}
Now value should be upped!.. {'key': ['hellostack', 1]}
from worker 2: {'key': ['hellostack', 1]}

任何? :O)

编辑:可能重复,不关注两个单独的进程,也没有谈论里面有列表的字典。然而,诚然非常相似,实际上答案让我得到答案。所以我将暂时搁置。

2 个答案:

答案 0 :(得分:2)

这是可变值的副作用以及多处理在进程之间同步数据的方式。

你从multiprocessing.Manager获得的dict不是某种共享内存。它通过消息显式同步到子流程,当经理注意到修改时

它如何注意到修改?

简单:只需使用将事物与其他进程同步的代理覆盖dict的所有修改方法。您可以在python源代码中看到代理方法here的列表。

让我们逐行查看您的示例工作者:

d["key"] = []    #Creating empty dict item

好的,__setitem__已调用,代理会注意到更改。

d["key"]+=["hellostack"] #Adding first value

此处几乎相同,首先是__getitem__,没有同步,然后__setitem__来设置新值。

d["key"]+=[1]    #Adding second value

与前一个相同,首先添加项目,然后重新设置。

d["key"][1]+=2 #<<<< ISSUE HERE - Modifying second value does nothing

好的,__getitem__获取列表(不是ListProxy!),然后将其修改为 inplace ,列表是可变值。 DictProxy永远不会看到__setitem__来电,也绝不会同步任何内容。所以worker2永远不会看到这种变化。

答案 1 :(得分:1)

这就解决了我的问题。注释掉了不起作用的行,并在通讯中解释了新代码。感谢Schlenk提供了很好的解释&lt; 3并感谢Bharel链接可能的重复&lt; 3:

valuation_period_end_date
2013-09-03    17.564700
2013-09-04    17.608500
2013-09-05    17.696100
2013-09-06    17.659300
2013-09-09    17.734700
2013-09-10    17.808300
2013-09-11    17.823100
2013-09-12    17.704900
....
Name: CLASS F, Length: 984, dtype: float64