我有一本作者字典,每位作者都是一本书的字典,每本书都是一个单词列表。
我需要一个多处理场景,其中每个进程处理某个作者的某本书。
我尝试使用manager.dict()
和manager.list()
来实例化dicts和列表,但我的字典仍未填充。
这是声明主字典对象的方式。
import multiprocessing
from multiprocessing import Manager
manager = Manager()
allWords = manager.dict()
然后有一个函数read_author
执行任务分配
def read_author(author):
global allWords
allWords[author] = manager.dict() # each author is a dictionary of books
jobs = []
for f in os.listdir(auth_dir):
p = multiprocessing.Process(target=read_doc, args=(author, auth_dir, f,))
jobs.append(p)
p.start()
return jobs
这是制作我的流程的功能。
def read_doc(author_name, author_dir, doc_name):
global allWords
allWords[author_name][doc_name] = manager.list()
# document is loaded in the variable doc and it has a set of words
for word in doc.words:
allWords[author_name][doc_name].append(word)
文档是项目Gutenberg的txt文件,上面的doc
对象是使用spacy
构造的语法树。
read_doc
实际上涉及文档树解析和提取以及bigrams的计数。为简洁起见,我在代码示例中跳过了这些部分,但是我想要分配多个CPU内核的计数任务,这就是我使用多处理的原因。
答案 0 :(得分:1)
Python多处理指南建议尽可能避免共享状态
虽然我不清楚为什么你的代码不起作用,
我认为没有理由使用Manager
和共享状态
在此示例中,最终allWords
dict在主进程中汇编自Pool
进程中生成的单词列表:
def read_doc(author_name, doc_name):
# document is loaded in the variable doc and it has a set of words
return author_name, doc_name, list(doc.words)
def read_doc_param_gen(authors):
for author in authors:
auth_dir = deduce_auth_dir(author)
for f in os.listdir(auth_dir):
yield author, f
def read_authors(authors):
pool = multiprocessing.Pool()
allWords = collections.defaultdict(dict)
for author_name, doc_name, lst in pool.map(read_doc, read_doc_param_gen(authors)):
allWords[author_name][doc_name] = lst
return allWords
如果您需要更新某些GUI或其他内容,还有Pool.imap
。