代码之家  ›  专栏  ›  技术社区  ›  raul ferreira

在python中编写未来(asyncio)

  •  0
  • raul ferreira  · 技术社区  · 6 年前

    我试图在Python中实现一个简单的actor系统,以开发关于并发编程的一些见解。

    我主要关注的是在python中编写期货的一般任务,使用 asyncio 模块。

    假设我在一个单独的线程上运行了一个事件循环。

    import asyncio
    
    from threading import Thread
    
    loop = asyncio.new_event_loop()
    
    
    def run_event_loop(loop):
        asyncio.set_event_loop(loop)
        loop.run_forever()
    
    
    t = Thread(target=run_event_loop, args=(loop,))
    t.start()
    

    为了避免同步通信,我需要能够组成 Futures 不知何故。作为一个简单的例子,假设我想将两个结果结合起来 async 协同作战。

    我第一次(显然是错误的)尝试:

    async def f(x):
        fut = asyncio.run_coroutine_threadsafe(g(x / 2), loop)
        return fut
    
    async def g(x):
        return x * 2
    

    f(x) = x / 2

    g(x) = x * 2

    f(g(x)) = x

    我无法得出一个干净的解决方案来解决以下一般问题:

    x = 10
    
    future = asyncio.run_coroutine_threadsafe(f(x), loop)
    
    print(future)                    # <Future at 0x106f797f0 state=pending>
    
    print(future.result())           # <Future at 0x10677c780 state=finished returned float>
    
    print(future.result().result())  # 10.0
    

    理想情况下,我应该结合未来并执行一个 future.result() 最后。或者我想的都不对。

    1 回复  |  直到 6 年前
        1
  •  3
  •   abarnert    6 年前

    这里的根本问题是:

    fut = asyncio.run_coroutine_threadsafe(g(x / 2), loop)
    

    你在一个 async 函数,并尝试在同一线程的同一事件循环中运行另一个异步函数。你不需要 run_coroutine_threadsafe 为了这个;只是 await 它。

    如果你打电话怎么办 运行协程安全 不管怎样?那么你得到的是 concurrent.futures.Future . 如顶部所述 asyncio 医生,这和 asnycio.Future _ 模仿 一个并行的未来,但在它的掩护下,这是另一回事。您可以组合两个异步期货(来自同一事件循环),您可以组合两个并发期货,但不能组合具有异步期货的并发期货。

    您可以在异步的将来包装一个并发的将来(直接使用 wrap_future 或者,更常见的是,通过 run_in_executor )但是,您将要结束的是一个并发未来,它包含一个包装并发未来的异步未来,而这个并发未来仍然无法组合。