zoukankan      html  css  js  c++  java
  • python Gevent协程

    协程(微线程)是一种用户态的轻量级线程

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

    线程是通过cup来调度切换。

     优点:

    • 无需线程上下文切换的开销
    • 无需原子操作锁定及同步的开销
    • 方便切换控制流,简化编程模型
    • 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

    缺点:

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

    使用yield实现协程操作

    import time
    import queue
    def consumer(name):  #有yield的函数是一个生成器
        print("--->starting eating baozi...")
        while True:
            new_baozi = yield  #遇到yield 停止执行
            print("[%s] is eating baozi %s" % (name,new_baozi))
            #time.sleep(1) 
    def producer(): 
        r = con.next() #3.0以前的带有yield的next,3.0之后需要写成__next__,作用唤醒程序从yield的位置继续执行。
        r = con2.next()
        n = 0
        while n < 5:
            n +=1
            con.send(n)
            con2.send(n)
            print("is making baozi %s" %n )  
    if __name__ == '__main__':
        con = consumer("c1") #创建对象
        con2 = consumer("c2")
        p = producer()
    

    某个函数包含了yield,这意味着这个函数已经是一个Generator,它的执行会和其他普通的函数有很多不同。

    封装好的协程 Greenlet

    #coding:utf-8
    from greenlet import greenlet
    import time
    def texta():
        print (21)
        b.switch()  #1停止texta的运行,调到textb执行,3调到这个位置继续执行。
        print(22)
        time.sleep(2) #感受执行顺序
        b.switch()
    def textb():
        print(31)
        a.switch() #2停止textb的运行,调到texta刚才switch停止的位置继续执行。
        print(32) 
        
    a=greenlet(texta)
    b=greenlet(textb)
    a.switch() #执行texta
    

    gevent

    Gevent 可以实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet,  Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

    #coding:utf-8
    import gevent
    import time
    def texta():
        print (21)
        gevent.sleep(2) #遇到IO停2秒,往下执行textb,textb执行完texta到时间执行。
        print(22)
    
    def textb():
        print(31)
        gevent.sleep(1)#遇到IO停1秒,往下执行textc,textc执行完textb到时间执行。
        print(32) 
       
    def textc():
        print(41)
        gevent.sleep(0) #遇到IO停0秒,这时候texta/textb没到时间还在停止,执行下一条语句
        print(42) 
         
    gevent.joinall([
        gevent.spawn(texta),
        gevent.spawn(textb),
        gevent.spawn(textc),
    ])
    

      

  • 相关阅读:
    Adding timestamps to terminal prompts
    opensuse nvidia
    小物体检测
    openSUSE 多个GPU设置 深度学习 Caffe PyTorch 等
    openSUSE 高清屏设置
    手把手教你NLTK WordNet使用方法
    [ICCV 2019] Weakly Supervised Object Detection With Segmentation Collaboration
    Instance Segmentation入门总结
    [PAMI 2018] Differential Geometry in Edge Detection: accurate estimation of position, orientation and curvature
    [CVPR2017] Deep Self-Taught Learning for Weakly Supervised Object Localization 论文笔记
  • 原文地址:https://www.cnblogs.com/iexperience/p/9342446.html
Copyright © 2011-2022 走看看