python 协程(2)--asyncio和async/await

849 阅读2分钟

「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战

前言

接着上篇文章继续写,上篇文章

python 协程(1)

asyncio

asyncio是python3.4版本引入的标准库,看官方文档:

asyncio

The new asyncio module (defined in PEP 3156) provides a standard pluggable event loop model for Python, providing solid asynchronous IO support in the standard library, and making it easier for other event loop implementations to interoperate with the standard library and each other.

For Python 3.4, this module is considered a provisional API.

asyncio是用来编写并发代码的库,asyncio的编程模型是一个消息循环,我们从ayncio模块中直接获取一个eventloop的引用,然后把需要执行的协程放到event loop中执行。

看一段代码

import asyncio

@asyncio.coroutine
def hello():
    print("Hello world!")
    # 异步调用asyncio.sleep(1):
    r = yield from asyncio.sleep(1)
    print("Hello again!")

# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()
    1. @asyncio.coroutine把一个生成器hello标记为协程类型,
    1. asyncio创建一个事件循环对象
    1. 把协程放入事件循环中去执行
    hello() 首先会输出Hello world!, yield from关键字可以让我们方便调用另一个生成器,asyncio.sleep()也是一个协程,所以线程不会等待,而是直接中断并执行下一个消息循环。当asyncio.sleep()返回时,线程就可以从yield from拿到返回值,然后接着执行下一行语句。 把asyncio.sleep(1)看成是一个耗时1秒的IO操作,在此期间,主线程并未等待,而是去执行EventLoop中其他可以执行的coroutine了,因此可以实现并发执行

async/await

用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作。

为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读。

请注意,async和await是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:

  1. 把@asyncio.coroutine替换为async;
  2. 把yield from替换为await。

还以上述的hello为例

import asyncio


async def hello():
    print("Hello world!")
    # 异步调用asyncio.sleep(1):
    r=await asyncio.sleep(1)
    print("Hello again!")

# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()

把上述两种方式都执行一下

图片.png

方式二

图片.png 两次执行,结果是一致的。