python 协程 如何不被取消

我开始学习python中的协程,学习到asyncio.shieldasyncio.wait_for这两个函数的时候有一个想法。

我想写一个函数,这个函数会因为超时而被asyncio.wait_for而取消,但是又会因这个函数asyncio.shield而不被取消。

import asyncio
import time


async def factorial(name, number):
    f = 1
    for i in range(2, number + 1):
        print(f"Task {name}: Compute factorial({i})...")
        await asyncio.sleep(1)
        f *= i
    print(f"Task {name}: factorial({number}) = {f}")


async def main():
    try:
        await asyncio.wait_for(
            asyncio.shield(
                factorial("func", 3)
            ), timeout=0
        )
    except asyncio.TimeoutError:
        print("Time out")


asyncio.run(main())
time.sleep(1)

发现并没有成功。
后面修改了一下,但是蒙了。

async def main():
    try:
        await asyncio.wait_for(
            asyncio.shield(
                factorial("func", 3)
            ), timeout=0
        )
    except asyncio.TimeoutError:
        print("Time out")
        await asyncio.sleep(10)

感觉是因为main函数的执行结束取消了。
但是最后一句await ... 改成time.sleep(10)又不行了。
求解释解释。。。

阅读 2.3k
1 个回答

time.sleep会挂起整个线程(该例中也是整个进程),冻结事件循环(谁也别动)。
asyncio.sleep 并不是一回事,它是把控制交给主事件循环,自旋等待定时后,再向调度询问控制权。这样代码此处才有有可能切换到其他协程,形成异步。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏