什么是协程,Python协程基本用法

协程(coroutine)可以理解为是线程的优化,又称之为轻量级进程。它是一种比线程更节省资源、效率更高的系统调度机制。

协程具有这样的特点,即在同时开启的多个任务中,一次只执行一个,只有当前任务遭遇阻塞,才会切换到下一个任务继续执行。这种机制可以实现多任务的同步,又能够成功地避免线程中使用锁的复杂性,简化了开发。

早先的协程是使用生成器关键字 yield 来实现的,代码特别复杂难懂。自从 Python 3.5之后,确定了协程的语法,使得创建协程的方式得到改善。Python 中,能够实现协程的模块有多个,如 asyncio、tornado 或 gevent。

这里以 asyncio 为例,先来了解一下创建协程所用到的概念:

  • event_loop(事件循环):是一个协程处理函数的调用机制。程序会开启一个无限循环,当事件发生时,调用相应的协程函数。
  • coroutine(协程对象):指一个使用 async 关键字来定义的函数。调用该函数,会返回一个协程对象。该协程对象就是一个处于挂起状态的协程函数,需要注册到事件循环 event_loop 中,由事件循环 event_loop 进行调用。
  • task 任务:是对协程的进一步封装。
  • future:等同于 task,代表执行任务的结果。
  • async/await 关键字:Python 3.5 中用于定义协程的关键字,其中 async 用于定义一个协程,await 用于挂起阻塞的异步调用接口。

Python协程的基本用法

下面通过代码演示最基本的协程用法:

# 导入asyncio模块
import asyncio
#定义协程处理函数
async def demo(x):
    print(x)
    r = await asyncio.sleep(1)
    print(x,"again")
#生成协程对象,并传入 hello
coroutine = demo("C语言中文网")
loop = asyncio.get_event_loop()
try:
    #将协程注册到实现事件循环对象中,并开始运行。
    loop.run_until_complete(coroutine)
finally:
    #程序结束关闭事件循环对象
    loop.close()

运行结果为:

C语言中文网
C语言中文网 again

注意,以上程序代码只能用在 Python 3.5 以及后续版本。因为 async 和 await 关键字是 3.5 版本才新加入。并且,在 Python 3.7 版本及后续版本中,可以使用 asyncio.run(coroutine) 代替第10~16行的代码,它们是完全等价的。

上面的代码体现了实现协程的基本步骤:

  1. 使用 async 关键字定义协程处理函数;
  2. 生成协程对象;
  3. 调用 asyncio 中的 get_event_loop 函数获得事件循环对象;
  4. 调用事件循环对象的 run_until_complete 方法,运行协程处理函数。

协程VS线程

与线程相比,协程封装的内容更多,实现起来更容易。

开发者使用协程会少考虑很多事情。在默认情况下应优先使用协程。但是有一个特点要注意,协程是多任务的顺序执行,只有当前任务挂起后,才会切换到其他任务来执行;而线程是以 CPU 轮换的方式执行。

因此,两者的运行机制有着本质上的区别,这使得二者都不可被代替。也就是说,如果业务需求要每个并行线程的处理进度也要同步,那么使用协程将不是一个很好的方案。在实际工作中,应根据业务需要来灵活运用线程或协程。

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/22950.html

(0)
上一篇 2021年7月20日 10:57
下一篇 2021年7月20日 10:57

相关推荐

发表回复

登录后才能评论