基于python协程库谈协程

1、协程和线程的区别

线程

  • 操作系统自动调度
  • 线程间切换需要陷入内核(在内核态切换),线程上下文规模比协程重,切换线程更费时

协程

  • 用户程序自主切换协程,不由操作系统调度
  • 协程上下文比线程轻量,切换速度更快,并且不会陷入内核,开销更小。
  • 上下文的轻量体现在哪?
    • 线程上下文是标准的进程上下文,包含的信息比较多,比如:cpu相关寄存器、线程优先级、pid、打开文件、信号、目录等等
    • 协程上下文应该只有:当前函数局部变量、函数运行的位置等少量信息

2、Python的两个协程库

2.1 gevent

  • 特点
    • 使用monkey patch(猴子补丁)替换了标准库,你以为调用的是标准库的方法,实际已经被替换成gevent的自己的方法,遇到的阻塞调用,会自动让出cpu
  • 基于libev去做的事件循环
  • TODO
    • gevent库包含内容挺多,之后在去了解其使用和实现原理(2022.04.12)

2.2 asyncio

  • 特点
    • asyncio控制权在自己手上,需要自己显式让出cpu
  • 使用要点
    • 使用asyncio库的装饰器将函数标记为协程
    • 将所以函数形成的数组放入事件循环
    • 开启,就会自动执行事件循环
  • 注意点
    • asyncio是Python标准库,在Python 3.5版本,使用async/await关键字简化了 asyncio库的操作。

2.3 两个方法的区别

  • gevent是自动挡,asyncio是手动挡
  • gevent可以使用monkey patch去替换原生接口(sleep,io请求接口等),自动注册到eventloop。asyncio需要使用相关的异步io方法才行。
  • 其实这样看来,asyncio貌似好一点,更清晰吧。

2.4 从两个方法看协程的特点

  • 协程的切换,需要用户程序主动地让出cpu(gevent也是采用monkey patch加入了自己的逻辑去主动让出的)
  • 在需要阻塞等待的地方,就需要让出cpu。需要等待的场景比如:
    • 操作磁盘io
    • 操作网络io
    • 需要sleep方法
  • 这些阻塞方法都不能使用原始的,必须是经过协程库去处理,这是协程能够在阻塞时自动切换的关键所在。

迭代器,生成器

  • 生成器设计初衷不是用来实现协程,而是
    • 1、提供函数挂起能力,减少回调函数的使用
    • 2、减少内存的消耗,动态的生成数据
  • 现在python社区有意分离生成器与协程的关系
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值