python multiprocessing.Processgetting在尝试返回结果时会生成AssertionError吗?

时间:2018-08-17 13:27:15

标签: python python-3.x multiprocessing python-multithreading

我正在尝试使用multiprocessing来完成一个非常慢的任务。如下面的代码所示,每个进程都应返回一些结果(return_dict)。我最初使用1万行数据集(存储在docs.txt文件中的数据,大约70mb)测试了此代码,并且代码按预期运行。但是,当我将脚本用于整个数据集(大约5.6gb)时,我得到了AssertionError,如问题底部所示。我想知道是否有人知道是什么原因造成的,以及我如何能够避免它。谢谢。

from multiprocessing import Process, Manager
import os, io, numpy
from gensim.models.doc2vec import Doc2Vec

def worker(i, data, return_dict):
    model = Doc2Vec.load("D:\\Project1\\doc2vec_model_DM_20180814.model")
    results = numpy.zeros((len(data), model.vector_size))
    for id, doc in enumerate(data):
        results[id,:] = model.infer_vector(doc, alpha = 0.01, steps = 100)
    return_dict[i] = results

if __name__ == '__main__':
    import time
    a  = time.time()
    path = "D:\\Project1\\docs.txt"    # <<=== data stored in this file
    data = []
    manager = Manager()
    jobs = []
    return_dict = manager.dict()

    with io.open(path, "r+", encoding = "utf-8") as datafile:
        for id, row in enumerate(datafile):
            row = row.strip().split('\t')[0].split()
            data.append(row)

    step = numpy.floor(len(data)/20)
    intervals = numpy.arange(0, len(data), step = int(step)).tolist()
    intervals.append(len(data))

    for i in range(len(intervals) - 1):
        p = Process(target=worker, args=(i, data[intervals[i]:intervals[i+1]], return_dict))
        jobs.append(p)
        p.start()
    for proc in jobs:
        proc.join()

    results = numpy.zeros((len(data), 1000))
    start = 0
    end = 0
    for _, result in return_dict.items():    #<<===Where error happens
        end = end + result.shape[0]
        results[start:end,:] = result[:,:]
        start = end

    print(time.time() - a)

错误消息:

Traceback (most recent call last):
  File "D:\Project1\multiprocessing_test.py", line 43, in <module>
    for _, result in return_dict.items():
  File "<string>", line 2, in items
  File "C:\ProgramData\Anaconda3\lib\multiprocessing\managers.py", line 757, in _callmethod
    kind, result = conn.recv()
  File "C:\ProgramData\Anaconda3\lib\multiprocessing\connection.py", line 250, in recv
    buf = self._recv_bytes()
  File "C:\ProgramData\Anaconda3\lib\multiprocessing\connection.py", line 318, in _recv_bytes
    return self._get_more_data(ov, maxsize)
  File "C:\ProgramData\Anaconda3\lib\multiprocessing\connection.py", line 337, in _get_more_data
    assert left > 0
AssertionError

2 个答案:

答案 0 :(得分:0)

我猜您正在使用所有可用的内存。 dict.items()为您的字典创建一个副本,其中包含所有项目并占用大量内存。最好使用dict.iteritems()遍历您的结果。

编辑:对不起,起初我没有注意到python-3标签。在Python3中,dict.items()不再返回副本,应该可以使用。

多处理中connection.py的相关代码为

left = _winapi.PeekNamedPipe(self._handle)[1]
assert left > 0

您是否正在使用Windows?所以我想这是一些与Windows相关的问题,似乎PeekNamedPipe返回0。

答案 1 :(得分:0)

这是我的情况和解决方案。希望这会有所帮助! 我有一个函数可以处理名为“ func”的

partial_func = partial(func,a=params1,b=params2)
for i, _ in enumerate(pool.imap(partial_func, [1]))):
    pass

根本原因是我传递给“ partial_func ”的params1和params2太大。