asyncio协程性质与原理
# 1
'''
import asyncio async def main(): print('hello') await asyncio.sleep(1) print('world') if __name__=="__main__": asyncio.run(main()) # hello # world
用async定义的函数,可以叫协程函数、异步函数,本文统一叫协程函数。
调用协程函数返回的对象叫协程对象。
关键字 await 调用协程函数,也可以叫等待、等待调用,这里统一叫等待。
'''
# 二
'''
import asyncio import time async def say_after(delay,what): 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、asyncio.run() 函数用来运行一个协程函数,比如上文中 asyncio.run(main())
2、await关键字等待一个协程函数
'''
# 3
'''
# 用asyncio.create_task() 调用协程函数,生成一个asyncio的任务,然后用await等待这个任务。
import time ,asyncio async def say_after(delay,what): await asyncio.sleep(delay) print(what) async def main(): task1 = asyncio.create_task(say_after(1, 'hello')) task2 = asyncio.create_task(say_after(2, 'world')) print(f"started at {time.strftime('%X')}") # Wait until both tasks are completed (should take # around 2 seconds.) await task1 await task2 print(f"finished at {time.strftime('%X')}") if __name__=="__main__": asyncio.run(main())
'''
# 4
'''
如果一个对象可以在 await 语句中使用,那么它就是 可等待 对象。
可等待 对象有三种主要类型: 协程, 任务 和 Future.
1、协程
await 等待协程
import asyncio async def nested(): return 42 async def main(): # Nothing happens if we just call "nested()". # A coroutine object is created but not awaited, # so it *won't run at all*. nested() # Let's do it differently now and await it: print(await nested()) # will print "42". asyncio.run(main())
'''
# 5
'''
任务 被用来设置到系统日程里以便 并发 执行的协程。本质上是一个协程,需要用await调用。
当一个协程通过 asyncio.create_task() 等函数被打包为一个 任务,该协程将自动排入日程等待立即运行:
第9行,task是一个future对象,可以取消任务、添加回调等,下文会提及。
import asyncio async def nested(): return 42 async def main(): # Schedule nested() to run soon concurrently # with "main()". task=asyncio.create_task(nested()) # "task" can now be used to cancel "nested()", or # can simply be awaited to wait until it is complete: await task asyncio.run(main())
'''
# 6
'''
以下文字来自官网:
Future 是一种特殊的 低层级 可等待对象,表示一个异步操作的 最终结果。
当一个 Future 对象 被等待,这意味着协程将保持等待直到该 Future 对象在其他地方操作完毕。
在 asyncio 中需要 Future 对象以便允许通过 async/await 使用基于回调的代码。
通常情况下 没有必要 在应用层级的代码中创建 Future 对象。
Future 对象有时会由库和某些 asyncio API 暴露给用户,用作可等待对象:
一个很好的返回对象的低层级函数的示例是 loop.run_in_executor()
import asyncio async def nested(): return 42 async def show(): return "bobby" async def main(): await nested() # this is also valid: await asyncio.gather( nested(), show() ) asyncio.run(main())
'''
# 7
'''
asyncio.run(coro, *, debug=False)
此函数运行传入的协程,负责管理 asyncio 事件循环并 完结异步生成器。
当有其他 asyncio 事件循环在同一线程中运行时,此函数不能被调用。
如果 debug 为 True,事件循环将以调试模式运行。
此函数总是会创建一个新的事件循环并在结束时关闭之。它应当被用作 asyncio 程序的主入口点,
import asyncio async def foo(): return 42 async def foo2(): return 43 async def main(): task=asyncio.create_task(foo()) return await task # await task # return 'main1' async def main2(): task2=asyncio.create_task(foo2()) return await task2 print(asyncio.run(main())) print(asyncio.run(main2()))
# 42
# 43
# asyncio.run(fn()) 函数的返回结果就是调用函数 fn() 返回的结果
# await task 表达式的值就是task返回的值
'''
# 8
'''
四、创建任务的函数
asyncio.create_task(coro)
将 coro 协程 打包为一个 Task 排入日程准备执行。返回 Task 对象。
该任务会在 get_running_loop() 返回的循环中执行,如果当前线程没有在运行的循环则会引发 RuntimeError。
此函数 在 Python 3.7 中被加入。在 Python 3.7 之前,可以改用低层级的 asyncio.ensure_future() 函数。
async def coro():
...
# In Python 3.7+
task = asyncio.create_task(coro())
...
# This works in all Python versions but is less readable
task = asyncio.ensure_future(coro())
'''
# 9
'''
asyncio.sleep(delay, result=None, *, loop=None)
参数:
阻塞 delay 指定的秒数。
如果指定了 result,则当协程完成时将其返回给调用者。
sleep() 总是会挂起当前任务,以允许其他任务运行。
import asyncio import datetime async def display_date(): loop = asyncio.get_running_loop() end_time = loop.time() + 5.0 while True: print(datetime.datetime.now()) if (loop.time() + 1.0) >= end_time: break await asyncio.sleep(1) asyncio.run(display_date()) 2022-10-10 17:29:50.974155 2022-10-10 17:29:51.975082 2022-10-10 17:29:52.976010 2022-10-10 17:29:53.976938 2022-10-10 17:29:54.977911
'''
# 10
'''
六、并发运行任务
asyncio.gather(*aws, loop=None, return_exceptions=False)
参数:
aws 表示序列中的 可等待对象。
return_exceptions 表示是是将异常立即返回,还是聚合到结果列表里。
如果 aws 中的某个可等待对象为协程,它将自动作为一个任务加入日程。
如果所有可等待对象都成功完成,结果将是一个由所有返回值聚合而成的列表。结果值的顺序与 aws 中可等待对象的顺序一致。
如果 return_exceptions 为 False (默认),所引发的首个异常会立即传播给等待 gather() 的任务。aws
序列中的其他可等待对象 不会被取消 并将继续运行。
如果 return_exceptions 为 True,异常会和成功的结果一样处理,并聚合至结果列表。
如果 gather() 被取消,所有被提交 (尚未完成) 的可等待对象也会 被取消。
如果 aws 序列中的任一 Task 或 Future 对象 被取消,它将被当作引发了 CancelledError 一样处理 --
在此情况下 gather() 调用 不会 被取消。这是为了防止一个已提交的 Task/Future 被取消导致其他
Tasks/Future 也被取消。
如果 gather 本身被取消,则无论 return_exceptions 取值为何,消息都会被传播(propagated)。
'''
# 11
'''
九、wait函数
asyncio.wait(aws, *, loop=None, timeout=None, return_when=ALL_COMPLETED)
并发运行 aws 指定的 可等待对象 并阻塞线程直到满足 return_when 指定的条件。
如果 aws 中的某个可等待对象为协程,它将自动作为任务加入日程。
aws必须为容器
返回两个 Task/Future 集合: (done, pending)。
用法:
done, pending = await asyncio.wait([aws, ])
如指定 timeout (float 或 int 类型) 则它将被用于控制返回之前等待的最长秒数。
请注意此函数不会引发 asyncio.TimeoutError。当超时发生时,未完成的 Future 或 Task 将在指定秒数后被返回。
import asyncio async def foo(): return 42 async def main(): task = asyncio.create_task(foo()) done, pending = await asyncio.wait([task, ]) if task in done: print('done') asyncio.run(main())
'''
# 11
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下