在python中自动生成多处理管理器()字典

我正在使用自动修复功能在多处理设置中存储数据.但是,我无法弄清楚如何将它合并到多处理管理器功能中.

我的自动生成代码来自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))

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

是否有可能将Manager.dict()转为autovivifacte?

———更新日期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似乎是一个性能影响. (我的Dicts遇到200Mb)

———更新8-12-2013 ——–
在我的应用程序中,dict.update()只被命中一次,所以即使Dict是〜200Mb,总的来说它不会对性能产生很大影响……

最佳答案 多处理管理器()为字典或列表提供代理.对子进程中的manager.Dict()的任何突变都不会被存储/保持跟踪.因此,需要将突变复制到属于Manager的代理变量.

(另见:
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 

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

点赞