Python协程介绍以及优缺点 Greentlet和Gevent的使用

鳄鱼君

发表文章数:642

热门标签

,

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » Python协程介绍以及优缺点 Greentlet和Gevent的使用

协程,又称微线程,纤程。英文名Coroutine。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:

协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

优点:

  1. 无需线程上下文切换的开销
  2. 无需原子操作锁定及同步的开销:”原子操作(atomic operation)是不需要synchronized”,所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分。视作整体是原子性的核心。
  3. 方便切换控制流,简化编程模型
  4. 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

缺点:

  1. 无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。
  2. 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

符合以下条件才能称之为协程:

  1. 必须在只有一个单线程里实现并发
  2. 修改共享数据不需加锁
  3. 用户程序里自己保存多个控制流的上下文栈
  4. 一个协程遇到IO操作自动切换到其它协程

Greenlet

greenlet是一个用C实现的协程模块,相比与python自带的yield,它可以使你在任意函数之间随意切换,而不需把这个函数先声明为generator,我们来看一个简单的列子:

 # pip install greenlet
from greenlet import greenlet
def test1():
    print('鳄鱼君1号')
    gr2.switch() # 切换到test2
    print('鳄鱼君4号')
    gr2.switch()

def test2():
    print('鳄鱼君2号')
    gr3.switch() # 切换到test3
    print('鳄鱼君5号')
    gr3.switch()

def test3():
    print('鳄鱼君3号')
    gr1.switch()  # 切换到test1
    print('鳄鱼君6号')

gr1 = greenlet(test1) # 启动一个协程
gr2 = greenlet(test2)
gr3 = greenlet(test3)
gr1.switch()  # 切换

# 鳄鱼君1号
# 鳄鱼君2号
# 鳄鱼君3号
# 鳄鱼君4号
# 鳄鱼君5号
# 鳄鱼君6号

以上代码是通过switch()方法来手动实现切换

Gevent

Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

import gevent
def func1():
    print('鳄鱼君1号...')
    gevent.sleep(2)  # 模仿IO操作,切换
    print('鳄鱼君6号...')


def func2():
    print('鳄鱼君2号...')
    gevent.sleep(1) # 模仿IO操作,切换
    print('鳄鱼君5号...')

def func3():
    print('鳄鱼君3号...')
    gevent.sleep(0) # 模仿IO操作,切换
    print('鳄鱼君4号...')

gevent.joinall([
    gevent.spawn(func1),#启动三个协程
    gevent.spawn(func2),
    gevent.spawn(func3),
])

# 鳄鱼君1号...
# 鳄鱼君2号...
# 鳄鱼君3号...
# 鳄鱼君4号...
# 鳄鱼君5号...
# 鳄鱼君6号...

通过gevent实现单线程下的多socket并发

标签:

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Python协程介绍以及优缺点 Greentlet和Gevent的使用》 发布于2020-06-24

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

3 + 7 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册