• asyncio.sleep


    asyncio.sleep

    协程对象来执行
    import asyncio
    import time
    
    
    async def coro_test():
        print(time.time())
    
    async def say_after(delay, what):
        # await coro_test()
        await asyncio.sleep(delay)
        print(what)
    
    
    async def main():
        print(f"started at {time.strftime('%X')}")
    
        await say_after(1, 'hello')
        await say_after(2, 'world')
    
        print(f"finished at {time.strftime('%X')}")
    
    
    asyncio.run(main())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    运行逻辑:

    1, asyncio.run(main()) 启动一个事件循环,将入口点main()协程对象传入,生成一个对应的任务task_main 。

    2,事件循环运行任务task_main,然后执行main()第1条代码:print(f"started at {time.strftime(‘%X’)}") 。

    3,接着执行main()第2条代码:await say_after(1, ‘hello’),

    ​ 第2条代码首先生成一个say_after(1, ‘hello’)协程对象,同时生成该协程对象对应的 task_1 。

    (在执行await语句时, 会交回控制权)

    await语法,task_main任务将控制权返回给事件循环,同时告诉事件循环需要等待 task_1 才能继续运行。

    4,事件循环获得控制权后,发现此时有两个任务task_main和 task_1,同时task_main在等待 task_1,

    于是会去执行 task_1任务 。

    5,task_1任务将执行第1条代码:await asyncio.sleep(1),同样会生成 asyncio.sleep(1) 协程对象 (asyncio.sleep 也是一个coroutine),生成对应的任务task_2,此时 await语句 将控制权返回给事件循环 。

    6 ,事件循环获得控制权后,发现此时有三个任务 task_main、task_1、task_2,由于task_main、task_1都处于等待状态,于是执行 task_2 。

    7,task_2在1秒后运行完成,返回控制权给事件循环 。

    8,事件循环获得控制权,发现此时有两个任务 task_main 和 task_1,同时 task_main 在等待 task_1,

    于是会去执行task_1任务 。

    9,task_1任务执行第2条代码:print(‘hello’),执行完成后,任务也运行结束,将控制权返回给事件循环;

    10,事件循环获得控制权后,发现此时有一个任务task_main,于是接着执行下一条代码:await say_after(2, ‘world’),继续重复上述过程 。

    event loop不能强行从一个task拿回控制器,需要task主动的把控制器交回去,交回的方式一种是 await , 一种是函数执行完成
    
    • 1
    asyncio.sleep 与 asyncio.create_task(asyncio.sleep())

    先看两段代码

    import asyncio
    
    async def main():
        await asyncio.create_task(asyncio.sleep(0.5))
    
    asyncio.run(main())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    import asyncio
    
    async def main():
        await asyncio.sleep(0.5)
    
    asyncio.run(main())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用 viztracer 工具看一下, 工具地址

    在这里插入图片描述

    在这里插入图片描述

    可以看到 main函数是直接调用了 asyncio.sleep,说明 await coroutine 时, 并没有将await 变成一个 task

    (网上是有一些文章说是await asyncio.sleep 时会把它变成一个task)

    当在一个task中 await coroutine 的时候, 这个task 并不会交出控制权, 会调用这个coroutine
    就像调用一个生成器一样, 等coroutine返回。(asyncio.sleep 源码中是新建了一个future)

    这样也是上面第6步的 task_main、task_1都处于等待状态, 执行task_2的原因。

  • 相关阅读:
    正则表达式的神奇世界:表达、匹配和提取
    自动化测试工具之Selenium IDE录制教程
    电子元器件
    linux-磁盘管理
    k8s docker cgroup驱动问题 —— 筑梦之路
    AI:70-基于机器学习的水质检预测
    纳米尺度下的单粒子追踪,厦门大学方宁团队用 AI 奏响「细胞里的摇滚」
    aarch64 arm64 部署 stable diffusion webui 笔记 【1】准备 venv 安装pytorch 验证cuda
    《最新出炉》系列初窥篇-Python+Playwright自动化测试-19-处理鼠标拖拽-中篇
    html 生成1-100的随机数
  • 原文地址:https://blog.csdn.net/henye007/article/details/126824776