协程的概念与用法

什么是协程

协程:一种比线程更加轻量级的存在,不同于进程、线程,更确切来说是一个特殊的函数,它拥有自己的寄存器、上下文、栈。协程调度切换时,将寄存器上下文和栈保存起来,切回来时恢复先前保存的寄存器上下文和栈。因此协程可以保留上一次调用时的状态,每次恢复运行就相当于进入上一次的调用状态,无需上下文切换的开销。

几种状态解读

阻塞:指程序未得到所需计算资源时被挂起的状态。网络I/O阻塞、磁盘I/O阻塞、用户输入阻塞

非阻塞:指程序在执行等待操作时,自身不被阻塞,可以继续处理其他事情

同步:指程序在完成任务时,需要和其他程序协调一致,例如:商品库存 同步意味着有序

异步:指程序在完成任务时,无需和其他程序协调,例如:爬虫 异步意味着无序

协程的用法

在 Python3.5 引入了 async/await 使得协程实现更加方便

首先我们用 async 来定义一个协程函数,用一个变量 coroutine 接收函数,此时 coroutine 是一个协程对象

async def execute(x):
    print('Number:', x)
# coroutine: <coroutine object execute at 0x00000258FF006648>
coroutine = execute(1)

导入异步模块 asyncio ,实例化一个事件循环对象,调用loop对象的run_until_complete方法,将 coroutine 注册到事件循环中,然后启动。

import asyncio
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine)

我们可以用 task 对象对 coroutine 作进一步封装,以获取RunningFinshed运行状态

task = loop.create_task(coroutine)
loop.run_until_complete(task)

 定义 task 对象,我们还可以直接通过 asyncioensure_future 方法,返回结果也是 task 对象,在绑定 task 对象之前,我们可以绑定 task 的回调函数,当 coroutine 对象执行完毕后调用

task = asyncio.ensure_future(coroutine)
task.add_done_callback(func_name)

有时我们需要注册多个任务到 loop循环上,只需将 tasks 以列表方式传入 asynciowait() 方法,再进行注册。(这样写没返回结果)

loop.run_until_complete(asyncio.wait(tasks))

在程序中实现异步,首先要进行挂起操作,当一个任务需要等待 IO 结果时可以使用 await 挂起当前任务,转去执行其他任务,待事件执行到尾部,回过来再执行一圈,例如:

response = await requests.get(url)  # 错误示范
# 正确示范,但requests不支持HTTP协议的异步操作:
async def get(url):
   return requests.get(url)

response = await get(url)

根据官方文档说明,await 后面的对象必须是如下格式之一:

1.一个原生coroutine对象。

2.一个由 types.coroutine 修饰的生成器,这个生成器可以返回 coroutine 对象。

3.一个包含 await 方法的对象返回的一个迭代器。

信号量

版权声明:
作者:hyzsj0106
链接:https://www.cxywy.com/?p=314
来源:程序员无垠
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录