【问题标题】:Processing a long list using Multiprocessing使用 Multiprocessing 处理长列表
【发布时间】:2015-03-01 20:32:52
【问题描述】:
output = mp.Queue()

def endScoreList(all_docs, query, pc, output):
    score_list = []
    for doc in all_docs:
        print "In process", pc
        score_list.append(some_score(doc, query))
        print "size of score_list is", len(score_list)
    output.put((doc, score_list))

if __name__ == '__main__':
    mp.freeze_support()
    num_of_workers = mp.cpu_count()
    doc_list = getDocuments(query)
    ## query is a list of strings.
    ## doc_list is a list of document names
    processes = [mp.Process(target = endScoreList, args = (doc_list, x, query, output)) for x in range(num_of_workers)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()
    results = [output.get() for p in processes]
    print results

我有一个文档名称列表all_docs,我必须将其数据与输入query 进行比较。这是使用我从some_score(doc, query) 获得的分数来完成的。文档列表约为 100k。我必须得到所有文件的分数。如何制作程序以并行生成分数。分数是相互独立的,所以最后我只需要合并所有返回的(doc, score) 列表。我试着做一个程序,但我不认为它是并行运行的。

请帮帮我。

我使用的是 Windows 64 位/i7。

【问题讨论】:

  • 是什么让您认为您的进程没有并行运行?
  • 虽然您显示的代码非常接近工作,但使用multiprocessing.Pool 及其map 方法之一(mapimap、@ 987654330@等)。
  • @SeanPedersen 实际上很慢。我在函数中打印了列表的大小,它的工作方式与没有 multithreading 时的工作方式相同。
  • @Blckknght 我也会试试的。

标签: python python-2.7 multiprocessing


【解决方案1】:

很难指出您当前的代码出了什么问题,因为您展示的示例存在许多问题(例如,您使用 // 引入注释,创建调用一个finalScore 函数并将doc_list 作为参数传递,两者均未定义)。

与其试图弄清楚你的代码发生了什么,我想提出一个可能更简单的替代解决方案。如果您使用multiprocessing.Poolmap 方法,无论池中有多少进程,您的工作都会被分配。

import multiprocessing as mp

def worker(doc):
    return doc, some_score(doc, "query")

if __name__ == "__main__":
    mp.freeze_support()
    p = mp.Pool() # default is a number of processes equal to the number of CPU cores
    scores = p.map(worker, all_docs)
    p.close()
    p.join()

这个简单的版本假设查询字符串是一个常量。如果不是这种情况,您可以将其作为参数传递给map 调用(或考虑改用starmap)。

【讨论】:

  • 我已经更正了您在文中指出的错误。它有助于您识别某些东西吗?
  • 好吧,您的代码的一般问题是您永远不会在进程之间细分doclist。也就是说,每个流程都在所有文档上运行(因此您对每个文档进行多次评分)。您可能可以修改您的代码以将完整文档列表的一部分传递给每个工作进程,并且它可能会起作用。我只是觉得使用multiprocessing.Pool 更容易。
  • 所以,你的意思是我应该将整个列表分成 8 个部分,即 8 个进程并在第一个代码中使用它们。我想知道的另一件事是,如何将具有多个参数的函数传递给map。我有一个doc_list 和一个query。我应该将它们作为元组列表传递,即(doc, query)
  • 如果您手动创建流程,是的,您会想要拆分输入(或者可能使用流程编号来迭代部分内容)。至于通过map 传递多个参数,您可以将值打包到数据结构中,然后在工作函数中解包,或者您可以使用starmap,它将每个元组或列表放入位置参数,如worker(*arg) .至于构建序列,我建议使用生成器表达式:p.starmap(worker, ((doc, query) for doc in all_docs))
  • 谢谢,我明白你的意思。基本上,mapstarmap 使我免于手动创建流程的麻烦,而且我也不必对数据进行切片。我会用 starmap 试试这个,看看效果如何。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
  • 2021-12-17
  • 1970-01-01
  • 2017-12-24
  • 2019-01-27
  • 2020-07-13
相关资源
最近更新 更多