如何使Python生成器执行异步?

时间:2018-11-08 18:46:14

标签: python asynchronous generator yield

我有一段看起来像这样的代码:

def generator():
    while True:
        result = very_long_computation()
        yield result

def caller():
    g = generator()
    for i in range(n):
        element = next(g)
        another_very_long_computation()

基本上,我想尽可能地重叠执行very_long_computation()another_very_long_computation()

是否有使发电机异步的简单方法?我希望生成器在产生result之后立即开始计算while循环的下一个迭代,以便(理想情况下)可以在成功的{{1 }}致电result

1 个答案:

答案 0 :(得分:3)

没有简单的方法,尤其是因为您拥有very_long_computationanother_very_long_computation而不是very_slow_io。即使您将generator移到了自己的线程中,您也会受到CPython全局解释器锁的限制,从而无法获得任何性能优势。

您可以将工作移到工​​作进程中,但是multiprocessing模块并不是它所假装的threading的直接替代品。它充满了怪异的复制语义,不直观的限制以及与平台有关的行为,并且通信量很大。

如果您将I / O与计算一起使用,那么将生成器的工作推到其自己的线程中至少要在I / O期间完成一些工作是很简单的:

from queue import Queue
import threading

def worker(queue, n):
    gen = generator()
    for i in range(n):
        queue.put(next(gen))

def caller():
    queue = Queue()
    worker_thread = threading.Thread(worker, args=(queue, n))
    worker_thread.start()
    for i in range(n):
        element = queue.get()
        another_very_long_computation()