Python多处理apply_async"断言左> 0"的AssertionError

时间:2017-12-07 10:11:30

标签: python multithreading python-3.x numpy pool

我正在尝试在池中异步加载numpy文件:

self.pool = Pool(2, maxtasksperchild = 1)
...
nextPackage = self.pool.apply_async(loadPackages, (...))
for fi in np.arange(len(files)):
    packages = nextPackage.get(timeout=30)
    # preload the next package asynchronously. It will be available
    # by the time it is required.
    nextPackage = self.pool.apply_async(loadPackages, (...))

方法" loadPackages":

def loadPackages(... (2 strings & 2 ints) ...):
    print("This isn't printed!')
    packages = {
        "TRUE": np.load(gzip.GzipFile(path1, "r")),
        "FALSE": np.load(gzip.GzipFile(path2, "r"))
    }
    return packages

在第一个"包之前#34;加载时,会发生以下错误:

  

Thread-8中的异常:Traceback(最近一次调用last):
  文件" C:\ Users \ roman \ Anaconda3 \ envs \ tsc1 \ lib \ threading.py",第914行,   在_bootstrap_inner中       self.run()文件" C:\ Users \ roman \ Anaconda3 \ envs \ tsc1 \ lib \ threading.py",第862行,in   跑       self._target(* self._args,** self._kwargs)文件" C:\ Users \ roman \ Anaconda3 \ envs \ tsc1 \ lib \ multiprocessing \ pool.py",line   463,在_handle_results       task = get()文件" C:\ Users \ roman \ Anaconda3 \ envs \ tsc1 \ lib \ multiprocessing \ connection.py",   第250行,在recv       buf = self._recv_bytes()文件" C:\ Users \ roman \ Anaconda3 \ envs \ tsc1 \ lib \ multiprocessing \ connection.py",   第318行,在_recv_bytes中       return self._get_more_data(ov,maxsize)File" C:\ Users \ roman \ Anaconda3 \ envs \ tsc1 \ lib \ multiprocessing \ connection.py",   第337行,在_get_more_data中       断言左> 0 AssertionError

我密切监视资源:内存不是问题,发生错误时我还有很多东西。 解压缩的文件只是简单的多维numpy数组。 单独使用具有更简单方法的池,并加载文件就可以了。只有在组合中才会失败。 (所有这些都发生在自定义keras生成器中。我怀疑这有用但谁知道。)Python 3.5。

这个问题的原因是什么?如何解释这个错误?

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

Python C核心代码中存在一个错误,该错误会阻止大于2GB的数据响应正确返回主线程。 您需要按照上一个答案中的建议将数据分成较小的块,或者不对该函数使用多处理

我将此错误报告给了python错误列表(https://bugs.python.org/issue34563),并创建了一个PR(https://github.com/python/cpython/pull/9027)对其进行修复,但要发布它可能需要一段时间。

如果您有兴趣,可以在我发布的链接的错误说明中找到有关导致错误的原因的更多详细信息

答案 1 :(得分:2)

它认为我通过小块检索数据找到了解决方法。就我而言,这是一份清单。

我有:

for i in range(0, NUMBER_OF_THREADS):
    print('MAIN: Getting data from process ' + str(i) + ' proxy...')
    X_train.extend(ListasX[i]._getvalue())
    Y_train.extend(ListasY[i]._getvalue())
    ListasX[i] = None
    ListasY[i] = None
    gc.collect()

更改为:

CHUNK_SIZE = 1024
for i in range(0, NUMBER_OF_THREADS):
    print('MAIN: Getting data from process ' + str(i) + ' proxy...')
    for k in range(0, len(ListasX[i]), CHUNK_SIZE):
        X_train.extend(ListasX[i][k:k+CHUNK_SIZE])
        Y_train.extend(ListasY[i][k:k+CHUNK_SIZE])
    ListasX[i] = None
    ListasY[i] = None
    gc.collect()

现在它似乎可行,可能是一次序列化较少的数据。 因此,如果您可以将数据细分为较小的部分,则可以克服该问题。祝你好运!