更新后多处理和dict为空[python3]

时间:2017-09-29 13:47:21

标签: python-3.x function dictionary concurrency python-multiprocessing

我在python3中的代码有一个问题: 我尝试了很多解决方案,但结果仍然相同。

import pprint
import concurrent
import multiprocessing
from concurrent import futures

class exempleStackOverFlow: 
    def __init__(self):
        self.dict1={}
        self.headers = {"header1","header2","header3"}

    def fillIn(self,key):
        response = {key:{'first':['1','2','3']}}
        self.dict1.update(response)
        pprint.pprint(response)

e =  exempleStackOverFlow()

def try_my_operation(item):
    try:
        e.fillIn(item)      
    except:
        print('error with item')

executor = concurrent.futures.ProcessPoolExecutor(2)
futures = [executor.submit(try_my_operation, item) for item in e.headers]
concurrent.futures.wait(futures)
print(e.dict1)

结果

{'header3': {'first': ['1', '2', '3']}}
{'header1': {'first': ['1', '2', '3']}}
{'header2': {'first': ['1', '2', '3']}}
{}

预期

 {'header3': {'first': ['1', '2', '3']}}
 {'header1': {'first': ['1', '2', '3']}}
 {'header2': {'first': ['1', '2', '3']}}
 {'header1': {'first': ['1', '2', '3']},
'header2': {'first': ['1', '2', '3']},
     'header3': {'first': ['1', '2', '3']}}

(或任何标题顺序)

我可能不明白这是怎么回事,我想对我的问题有所了解,当我进入时,dict1在结束时是空的 try_my_operation

如果没有多处理/并发(例如,如果我e.fillIn("headers1"),e.fillIn("headers2") ...并且在我可以获得dict1之后它确实更新。

感谢您以后的任何评论

2 个答案:

答案 0 :(得分:1)

我相信您正在寻找ThreadPoolExecutor,而不是ProcessPoolExecutor。

这里我使用多线程(没有并发)来获得预期的输出:

import pprint
from threading import Thread

class exempleStackOverFlow: 
    def __init__(self):
        self.dict1={}
        self.headers = ["header1","header2","header3"]

    def fillIn(self,key):
        response = {key:{'first':['1','2','3']}}
        self.dict1.update(response)
        pprint.pprint(response)

def try_my_operation(item):
    try:
        e.fillIn(item)
    except:
        print('error with item')

e =  exempleStackOverFlow()

for i in range(len(e.headers)):
    futures = Thread(target = try_my_operation, args = (e.headers[i],));
    futures.start();
    futures.join();

print(e.dict1)

不同之处在于多处理中的e不是共享对象,因此e不会在所有进程之间更新。在多线程中,它们共享相同的变量,因此可以按预期更新e

修改

我对并发不熟悉,但我确信它有类似的方法来共享类型和对象,例如显示multiprocessing doeshere和使用像here这样的管理器的对象{{} 3}}

如果速度是您正在寻找的,那么一定要使用多处理路线并使用像from multiprocessing.managers import BaseManager这样的经理分享您的对象。

答案 1 :(得分:1)

在@Treyten Care的帮助下

需要添加到我的初始帖子中:

from multiprocessing import Process, Manager 

class exempleStackOverFlow: 
        def __init__(self):
            manager = Manager()
            self.dict1 = manager.dict()

有了这个,我可以更新我的词典。 谢谢