如何并行运行生成器代码?

时间:2017-03-25 22:07:42

标签: python python-3.x parallel-processing generator concurrent.futures

我有这样的代码:

def generator():
    while True:
        # do slow calculation
        yield x

我想将慢速计算移到单独的进程中。

我在python 3.6中工作,所以我有concurrent.futures.ProcessPoolExecutor。如何使用它来并发生成器并不明显。

与使用map的常规并发场景的不同之处在于,此处没有任何内容可以映射(生成器永远运行),而且我们不想立即获得所有结果,我们希望将它们排队并且在计算更多结果之前,请等待队列未满。

我不必使用concurrentmultiprocessing也没关系。这是一个类似的问题,如何在发电机内使用它并不明显。

轻微扭曲:生成器返回的每个值都是一个大的numpy数组(大约10兆字节)。如何在不进行酸洗和去除油墨的情况下进行转移?我已经看过multiprocessing.Array的文档但是如何使用它传输一个numpy数组并不是很明显。

1 个答案:

答案 0 :(得分:0)

在这种情况下,我通常使用joblib库。它是一个基于多处理的并行计算框架。它支持精确的memmapping,适用于必须处理大型numpy数组的情况。我相信值得为你检查一下。

也许joblib的文档在这一点上不够明确,只显示了for循环的例子,因为你想使用一个生成器,我应该指出它确实适用于生成器。可以实现您想要的一个例子如下:

from joblib import Parallel, delayed
def my_long_running_job(x):
    # do something with x
# you can customize the number of jobs
Parallel(n_jobs=4)(delayed(my_long_running_job)(x) for x in generator())

编辑:我不知道你想要做什么样的处理,但如果它发布了GIL,你也可以考虑使用线程。这样您就不会遇到必须在进程之间传输大型numpy数组的问题,并且仍然可以从真正的并行性中获益。