• python中的协程:greenlet和gevent


    python中的协程:greenlet和gevent

    • 协程是一中多任务实现方式,它不需要多个进程或线程就可以实现多任务。

    1.通过yield实现协程:

    代码:

    
    import time
    
    def A():
        while 1:
            print('------A-----')
            time.sleep(0.1)
            yield()
    
    def B():
        while 1:
            print('-------B-----')
            time.sleep(0.1)
            next(a)
    
    a = A()
    B()
        
    

    执行结果:

    -------B-----
    ------A-----
    -------B-----
    ------A-----
    -------B-----
    ------A-----
    -------B-----
    ------A-----
    -------B-----
    ------A-----
    ··· 
    
    

    2.greenlet:

    • yield能实现协程,不过实现过程不易于理解,greenlet是在这方面做了改进。

    上代码:

    
    from greenlet import greenlet
    import time
    
    def A():
        while 1:
            print('-------A-------')
            time.sleep(0.5)
            g2.switch()
    
    def B():
        while 1:
            print('-------B-------')
            time.sleep(0.5)
            g1.switch()
    
    g1 = greenlet(A)  #创建协程g1
    g2 = greenlet(B)
    
    g1.switch()  #跳转至协程g1
    
    

    执行结果:

    -------A-------
    -------B-------
    -------A-------
    -------B-------
    -------A-------
    ···
    
    

    3.gevent:

    • greenlet可以实现协程,不过每一次都要人为的去指向下一个该执行的协程,显得太过麻烦。python还有一个比greenlet更强大的并且能够自动切换任务的模块gevent
    • gevent每次遇到io操作,需要耗时等待时,会自动跳到下一个协程继续执行。

    上代码:

    import gevent
    
    def A():
        while 1:
            print('-------A-------')
            gevent.sleep(1) #用来模拟一个耗时操作,注意不是time模块中的sleep
    
    def B():
        while 1:
            print('-------B-------')
            gevent.sleep(0.5)  #每当碰到耗时操作,会自动跳转至其他协程
    
    g1 = gevent.spawn(A) # 创建一个协程
    g2 = gevent.spawn(B)
    g1.join()  #等待协程执行结束
    g2.join()
    
    

    执行结果:

    -------A-------
    -------B-------
    -------B-------
    -------A-------
    -------B-------
    -------B-------
    -------A-------
    -------B-------
    -------B-------
    ···
    
    

    4.协程gevent完成回显服务器:

    import gevent
    from gevent import monkey,socket
    
    monkey.patch_all()   #有IO才做时需要这一句
    
    s = socket.socket(2,1)  #用的都是gevent模块中的socket,但用法一样
    s.setsockopt(1,2,1)
    s.bind(('',8080))
    s.listen(1024)
    
    def func_accept():
        while 1:
            cs,userinfo = s.accept()
            print('来了一个客户'+str(userinfo))
            g = gevent.spawn(func_recv,cs)  #每当有用户连接,增加一条协程
    
    def func_recv(cs):
        while 1:
            recv_data = cs.recv(1024)
            print(recv_data)  #程谁堵塞了,便会跳转至其他协程
            if len(recv_data) > 0:
                cs.send(recv_data)
            else:
                cs.close()
                break
    
    g1 = gevent.spawn(func_accept)
    g1.join()
    
    
    • gevent的代码风格和线程非常相似,运行出来后的效果也非常相似。

  • 相关阅读:
    Maven下载Jar包(bat脚本)
    在CentOS7环境下安装Mysql
    在CentOS7下安装JDK1.8
    教你如何进行暗网之旅
    在CentOS7下搭建Hadoop2.9.0集群
    查询IP地址的免费API
    HTTP请求代理类(GET 、 POST 、PUT 、DELETE)
    JAVA 实现 GET、POST、PUT、DELETE HTTP请求
    002---rest_framework认证组件
    001---CBV和restful规范
  • 原文地址:https://www.cnblogs.com/PrettyTom/p/6628569.html
Copyright © 2020-2023  润新知