我正在使用自动生成功能在多处理设置中存储数据。但是,我无法弄清楚如何将它合并到多处理管理器功能中。
我的自动更新代码来自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
外,我无法让它工作,但这并不是一个非常简洁的解决方案。< / p>
是否有可能将Manager.dict()置于autovivifacte?
--------- UPDATE 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 +,总的来说它不会对性能产生很大影响......
答案 0 :(得分:2)
多处理Manager()
为字典或列表提供代理。子流程中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
虽然这似乎是一些严重的开销,但在这种情况下它并不太糟糕,因为经理字典只需要在加入主进程之前更新()。