Python 使用多处理处理处理长列表

Python 使用多处理处理处理长列表,python,python-2.7,multiprocessing,Python,Python 2.7,Multiprocessing,我有一个文档名列表所有文档,我必须将其数据与输入的查询进行比较。这是使用我从一些评分(doc,query)中获得的评分来完成的。文件清单约为10万份。我必须得到所有文件的分数。我如何制作一个程序,以便并行生成分数。分数彼此独立,因此最后我只需合并所有返回的(doc,score)。我试图制作一个程序,但我不认为它是并行运行的 请帮帮我 我使用的是Windows 64位/i7。很难建议您当前的代码出了什么问题,因为您所展示的示例存在许多问题(例如,您使用/引入注释,创建调用finalScore函数并

我有一个文档名列表
所有文档
,我必须将其数据与输入的
查询
进行比较。这是使用我从
一些评分(doc,query)
中获得的评分来完成的。文件清单约为10万份。我必须得到所有文件的分数。我如何制作一个程序,以便并行生成分数。分数彼此独立,因此最后我只需合并所有返回的
(doc,score)
。我试图制作一个程序,但我不认为它是并行运行的

请帮帮我


我使用的是Windows 64位/i7。

很难建议您当前的代码出了什么问题,因为您所展示的示例存在许多问题(例如,您使用
/
引入注释,创建调用
finalScore
函数并将
doc\u list
作为参数传递的过程,这两个过程都没有定义)

我不想试图弄清楚你的代码是怎么回事,而是想建议一个可能简单得多的替代解决方案。如果你使用
多处理.Pool
map
方法,不管池中有多少个进程,你的工作都会被分配

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

这个简单的版本假定查询字符串是常量。如果不是这样的话,你可以把它作为一个参数传递到<代码> map < /Cult>调用中(或者考虑使用<代码>星图< /COD>)。.

是什么让您认为您的进程没有并行运行?虽然您所展示的代码非常接近工作状态,但使用
多处理.Pool
及其
map
方法之一(
map
imap
map\u async
等)可能实现更简单@SeanPedersen它实际上非常慢。我在函数中用打印列表的大小,它的工作方式与没有
多线程的情况下的工作方式相同。我也会尝试这些。我已经纠正了您在文本中指出的错误。这有助于您识别某些内容吗?嗯,您的代码的一般问题是您从不在进程之间细分
doclist
。也就是说,每个进程都在所有文档上运行(因此您会对每个文档进行多次评分)。您可能可以修改代码,将完整文档列表的一部分传递给每个工作进程,这可能会起作用。我只是认为使用
多处理.Pool
更容易。因此,您的意思是我应该将整个列表分成8个部分,即8个进程,并在第一个代码中使用它们。我想知道的另一件事是如何将一个函数传递给具有多个参数的
map
。我有一个
doc\u list
和一个
query
。我应该将它们作为元组列表传递吗,即
(doc,query)
?如果您手动创建流程,是的,您会希望分割输入(或者可以使用进程号来迭代内容的一部分).至于通过
map
传递多个参数,您可以将值打包到一个数据结构中,然后在worker函数中解包,或者使用
starmap
将每个元组或列表放入位置参数中,如
worker(*arg)
。至于构建序列,我建议使用生成器表达式:
p.starmap(worker,((doc,query)for doc in all_docs))
谢谢,我明白你的意思。基本上,
map
starmap
将我从手动创建流程的麻烦中解脱出来,而且我也不必对数据进行切片。我将尝试使用starmap,看看它的性能如何。
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()