我正在使用自动激活将数据存储在多处理设置中。但是,我不知道如何将它合并到多处理管理器功能中。

我的自动激活代码来自 Multiple levels of 'collection.defaultdict' in Python 并且在没有多处理发生时工作正常。

class vividict(dict):
    def __getitem__(self, item):
        try:
            return dict.__getitem__(self, item)
        except KeyError:
            value = self[item] = type(self)()
            return value

我的 multiproc 代码是相对简单的:
if __name__ == "__main__":
    man = Manager()
    ngramDict = man.dict()
    print(ngramDict) # {}
    s_queue = Queue()

    aProces = Process(target=insert_ngram, args=(s_queue,ngramDict,))
    aProces.start()
    aProces.join()
    print(ngramDict) # {}
    write_to_file()

在 insert_ngram 中读取、写入和更新字典:
def insert_ngram(sanitize_queue, ngramDict):
    ngramDict = Vividict() # obviously this overwrites the manager
    try:
        for w in iter(s_queue.get, None):
        if ngramDict[w[0]][w[1]][w[2]][w[3]][w[4]]:
            ngramDict[w[0]][w[1]][w[2]][w[3]][w[4]]+=int(w[5])
        else:
            ngramDict[w[0]][w[1]][w[2]][w[3]][w[4]]=int(w[5])
    print(ngramDict) # prints the expected ngramdict
    return
except KeyError as e:
    print("Key %s not found in %s" % (e, ngramDict))
except Exception as e:
    print("%s failed with: %s" % (current_process().name, e))

我尝试了一系列我认为很好的解决方案,但我无法让它工作,除了在 write_to_file 中调用 insert_ngram 但这并不是一个很好的解决方案。

是否有可能让 Manager.dict() 自动激活?

--------- 更新 6-12-2013 --------

由于 Manager() 提供代理,因此不会存储/跟踪子流程中对 manager.Dict() 的任何更改。 (另见: How does multiprocessing.Manager() work in python? )
这可以解决如下:
def insert_ngram(sanitize_queue, ngramDict):
    localDict = Vividict()
    localDict.update(ngramDict)
    #do stuff
    ngramDict.update(ngramiDict)

我正在等待我的机器完成一些任务,以便我可以看到它的执行情况。像这样上下复制 Dicts 似乎是一种性能打击。 (我的字典达到 200Mb+)

--------- 更新 8-12-2013 --------
在我的应用程序中,dict.update() 只被命中一次,所以即使 dict 是 ~200Mb+,总的来说它对性能的影响并不大......

最佳答案

多处理 Manager() 提供了字典或列表的代理。不会存储/跟踪子进程中对 manager.Dict() 的任何更改。因此,需要将突变复制到属于管理器的代理变量。
(另见: How does multiprocessing.Manager() work in python? )

这可以解决如下:

def insert_ngram(queue, managerDict):
    # create a local dictionary with vivification
    localDict = Vividict()
    # copy the existing manager.dict to the local dict.
    localDict.update(managerDict)
    #do stuff
    # copy the local dictionary to the manager dict
    managerDict.update(localDict)
    return

虽然这看起来像是一些严重的开销,但在这种情况下还不算太糟糕,因为管理器字典只需要在加入主进程之前更新()。

关于python - 在python中自动激活多处理管理器()字典,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20411926/

10-14 19:48
查看更多