【问题标题】:Throwing a coroutine to event loop without blocking [duplicate]将协程扔到事件循环而不阻塞[重复]
【发布时间】:2021-04-08 21:50:17
【问题描述】:

我已经使用 Python 多年了,最近我发现了异步编程。 但是,我在尝试实施我的想法时遇到了困难......

假设我有一个常规(同步)函数g(),它返回一个它计算的值。在这个函数内部,我想调用另一个函数,即异步并循环运行——我们将调用这个函数f()。函数f()g() 内部被调用,但g() 的返回值是在f() 甚至被调用之前计算的。但是,很明显,我希望 g() 返回它计算的值并继续“在后台”运行 f()

import asyncio


def g(a, b):
    y = a + b
    asyncio.run(f())    # This is blocking!
    return y


async def f():
    for _ in range(3):
        await asyncio.sleep(1)
        print("I'm still alive!")

print(g(3, 5))
# code async code continues here...


# Output:
# I'm still alive!
# I'm still alive!
# I'm still alive!
# 8

# Expected\Wanted:
# 8
# I'm still alive!
# I'm still alive!
# I'm still alive!

这样的事情可能吗?还是我错过了什么? 提前致谢!

【问题讨论】:

    标签: python python-3.x asynchronous async-await python-asyncio


    【解决方案1】:

    我认为存在一些误解。因此,首先,如果不使用threadprocess,您将无法真正同时拥有一些东西。 async 是基于回调的事件驱动架构的语法糖。

    简而言之,它们仍然在同一个线程中,并且如您所知,一个线程一次只能做一件事。如果你想让某种后台任务运行并打印"I'm still alive",那么async 不是你想要的。

    另外,你不好奇事件循环在哪里吗?循环由asyncio.run创建和管理,大致相当于:

    loop = asyncio.get_event_loop()
    loop.run_until_complete(f())
    

    所以你看,你需要运行/触发循环,它是阻塞的。


    基本上,异步编程不像你想象的那样工作(我猜)。里面没有魔法,它只是一个普通的阻塞事件循环。我们往里面添加了多个任务,所有的任务都在一个一个的运行。有些任务有回调函数,它会在循环中添加另一个任务。就是这样。

    【讨论】:

      猜你喜欢
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-18
      • 1970-01-01
      • 2019-11-15
      相关资源
      最近更新 更多