1、asyncio
- import asyncio
-
- # coroutine function: async开头的函数
- async def main():
- print('hello')
- await asyncio.sleep(1)
- print('world')
-
-
- coro = main() # coroutine object:协程对象
-
- # 当生成协程对象的时候,并不运行函数里面的程序。
- # 运行时需要两步走:进入 async 模式、把coroutine变成task
-
- asyncio.run(coro) # 创建 event loop 来跑 task
2、了解 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 把控制权交还给 event loop
- await say_after(2, 'world')
- print(f"finished at {time.strftime('%X')}") # 总共花了3秒
-
-
- coro = main() # coroutine object:协程对象
-
- asyncio.run(coro) # 创建 event loop 来跑 task
3、了解 asyncio.create_task
- import asyncio
- import time
-
- 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'))
-
- # create_task 可提前创建好 task
- # 到目前为止,两个 task 都已初始化到 event loop 里面了
-
- print(f"started at {time.strftime('%X')}")
- await task1
- await task2
- print(f"finished at {time.strftime('%X')}")
-
-
- '''
- task1 执行1s等待的时候,event loop 是空闲的,
- 它发现 task2 可以执行,就执行了一秒task2,
- 所以当 task1 执行完之后,task2 还剩下1秒等待需要执行,所以总体时间花了2秒
- async 很适合解决网络通讯的问题,因为网络通讯很多时间是在等待上的,也就是所谓的 io bound task。
- 等待的时间,可以去完成别的 task
- '''
- asyncio.run(main())

4、协程返回值怎么获取?
- import asyncio
- import time
-
- async def say_after(delay, what):
- await asyncio.sleep(delay)
- return f"{what} - {delay}"
-
- 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')}")
- ret1 = await task1 # 拿到返回值
- ret2 = await task2
- print(ret1)
- print(ret2)
-
- print(f"finished at {time.strftime('%X')}")
-
- asyncio.run(main())
5、了解 asyncio.gather
- import asyncio
- import time
-
-
- async def say_after(delay, what):
- await asyncio.sleep(delay)
- return f"{what} - {delay}"
-
-
- 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')}")
-
- # asyncio.gather的参数可以是若干个协程对象,task,以及asyncio.gather的返回值
- # 如果参数是协程对象,它会自动给转化为task
- # 最终返回一个list:['hello - 1', 'world - 2']
- ret = await asyncio.gather(task1, task2)
- print(ret)
-
- print(f"finished at {time.strftime('%X')}")
-
- asyncio.run(main())
6、了解 asyncio.gather 之后优化一下代码
- import asyncio
- import time
-
- async def say_after(delay, what):
- await asyncio.sleep(delay)
- return f"{what} - {delay}"
-
- async def main():
-
- print(f"started at {time.strftime('%X')}")
-
- # 直接将协程对象放到 asyncio.gather 中,它会自动变为 task,再逐个 await,
- # 最后返回一个列表式的结果:['hello - 1', 'world - 2']
- # 协程的意义:同一时间只有一个任务在跑,它只是想办法充分利用中间的等待时间
- # 协程对象只有变成了 task 才能被执行,
- # 而 await 和 gather 都是隐式地将协程对象变成了 task
- ret = await asyncio.gather(
- say_after(1, 'hello'),
- say_after(2, 'world')
- )
- print(ret)
-
- print(f"finished at {time.strftime('%X')}")
-
- asyncio.run(main())