gpt4 book ai didi

python - 在不产生事件循环的情况下调用协程

转载 作者:太空狗 更新时间:2023-10-30 01:10:54 27 4
gpt4 key购买 nike

出于可读性原因,我可能会分解代码。所以

async coro_top():
print('top')
print('1')
# ... More asyncio code

print('2')
# ... More asyncio code

...变成类似的东西

async coro_top():
print('top')
await coro_1()
await coro_2()

async coro_1()
print('1')
# ... More asyncio code

async coro_2()
print('2')
# ... More asyncio code

但是,额外的await意味着它们并不严格等同

  • 另一个并发任务可以在 print('top')print('1') 之间运行代码,因此更有可能出现竞争条件某些算法。

  • 产生事件循环(大概)有一点开销

那么有没有一种方法可以在不产生事件循环的情况下调用协程来避免上述情况?

最佳答案

问题的前提是不正确的:与人们的预期相反,await 不会 自动屈服于事件循环。您可以轻松测试:

async def noop():
pass

async def busy_loop(msg):
while True:
print(msg)
await noop()

# keeps printing 'a', the event loop is stuck
asyncio.get_event_loop().run_until_complete(
asyncio.gather(busy_loop('a'), busy_loop('b')))

虽然busy_loop一直在等待,但它仍然阻塞了事件循环,以至于其他任务不会运行,甚至取消它也是不可能的。这是因为它等待的 noop 协程从不暂停执行。

await some_coroutine() 并不意味着“安排 some_coroutine() 并屈服于事件循环,在它完成时恢复”。它的意思是“开始执行 some_coroutine() 并且,如果/当它选择暂停时,一起暂停”,并假设前者可以 leadbugs .

换句话说,分解后的代码真的等同于重构前的代码。在 print('top')print('1') 之间执行另一个任务的唯一方法是一个新的 await在它们之间添加(一个实际上暂停了协程),但对于原始代码也可以这样说。

There is (presumably) a slight overhead in yielding the event loop

存在开销,但它与函数调用的开销相当,而不是运行事件循环迭代的显着更大的开销。

关于python - 在不产生事件循环的情况下调用协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55556474/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com