`Pool。* _ async`函数从未准备好

时间:2017-09-27 15:03:07

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

import threading
import multiprocessing.dummy as mt
import numpy as np


if __name__ == '__main__':
    n = 6
    a = np.zeros((n, n))

    def f(i, j):
        a[i, j] = i + j

    with mt.Pool() as pool:
        r = pool.starmap_async(f, ((i, j) for i in range(n) for j in range(n)))

    r.wait()
    print(a)

上面的代码段会在r.wait()处阻止自己。但如果将其改为

import threading
import multiprocessing.dummy as mt
import numpy as np


if __name__ == '__main__':
    n = 6
    a = np.zeros((n, n))

    def f(i, j):
        a[i, j] = i + j

    with mt.Pool() as pool:
        pool.starmap(f, ((i, j) for i in range(n) for j in range(n)))

    print(a)

将立即打印a的内容。那么为什么第一个片段中的r从未准备好? (Python版本:Python 3.6.2 :: Anaconda custom (64-bit),在Linux下)

1 个答案:

答案 0 :(得分:2)

问题是你在with区之外等待。一旦退出with块,池就会terminated,这会阻止您完成任何任务。来自javadocs:

  

池对象现在支持上下文管理协议 - 请参阅上下文管理器类型。 __enter__()返回池对象,__exit__()调用terminate()

...

  

terminate()

     

立即停止工作进程而不完成   出色的工作。当池对象被垃圾收集时   terminate()将立即被调用。

将调用移至r.wait()块内的with可解决此问题。