美文网首页
协程库 gevent

协程库 gevent

作者: 领悟悟悟 | 来源:发表于2018-02-23 16:18 被阅读0次

    gevent,它是一个并发网络库。它的协程是基于greenlet的,并基于libev实现快速事件循环(Linux上是epoll,FreeBSD上是kqueue,Mac OS X上是select),协程阻塞时会自动调度(前提是打猴子补丁)

    def demo_00():
        import time
        import gevent
        #from gevent import monkey 
        #monkey.patch_all()
        '''
            也可以用gevent中提供的sleep函数替代time.sleep
            一般推荐使用猴子补丁
        '''
        def func(a,b):
            print(a,b)
            time.sleep(3) # 标准库time.sleep是阻塞式的
    
        f1 = gevent.spawn(func, 1,2)
        f2 = gevent.spawn(func,3,4)
    
        print(f1.started)
        print(f2.started)
        f1.join() # 此时是f1执行完毕才执行f2  >> 1 2 休眠 3 4 休眠
        f2.join() # 去掉注释 f1休眠期间会打印 3,4 
    
    协程的执行方法.join/.start

    join是阻塞式执行。 start是非阻塞式的即父协程结束,程序结束

    def demo_01():
        import gevent
        def func():
            print('协程休眠')
            gevent.sleep(3) 
            print('休眠结束')
    
        f1 = gevent.spawn(func)   
        f1.start()
        time.sleep(1)
    
    • ”gevent.joinall()”方法会等待所有传入的greenlet协程运行结束后再退出, 这个方法可以接受一个”timeout”参数来设置超时时间,单位是秒。等待时间超过还未结束便不会继续等待。

    • greenlet一个协程运行完后,必须显式切换,不然会返回其父协程。而在gevent中,一个协程运行完后,它会自动调度那些未完成的协程。

    def demo_02():
        import gevent
        def test1():
            print(12)
            gevent.sleep(0)
            print(34)
    
        def test2():
            print(56)
            gevent.sleep(0)
            print(78)
        jobs = [gevent.spawn(test1),gevent.spawn(test2)]
        gevent.joinall(jobs,timeout=5)
        print([job.exception for job in jobs])
    
    协程函数的执行状态,返回值与异常

    协程状态有已启动和已停止,分别可以用协程对象的”started”属性和”ready()”方法来判断。对于已停止的协程,可以用”successful()”方法来判断其是否成功运行且没抛异常。如果协程执行完有返回值,可以通过”value”属性来获取。另外,greenlet协程运行过程中发生的异常是不会被抛出到协程外的,因此需要用协程对象的”exception”属性来获取协程中的异常。

    def demo_03():
        import gevent
    
        def win():
            return 'You win!'
    
        def fail():
            raise Exception('You failed!')
    
        winner = gevent.spawn(win)
        loser = gevent.spawn(fail)
    
        print(winner.started)  # True
        print(loser.started ) # True
    
        # 在Greenlet中发生的异常,不会被抛到Greenlet外面。
        # 控制台会打出Stacktrace,但程序不会停止
        try:
            gevent.joinall([winner, loser])
        except Exception as e:
            # 这段永远不会被执行
            print('This will never be reached')
    
        print(winner.ready() ) # True
        print(loser.ready() ) # True
    
        print(winner.value)  # 'You win!'
        print(loser.value) # None
    
        print(winner.successful() ) # True
        print(loser.successful() ) # False
    
        # 这里可以通过raise loser.exception 或 loser.get()
        # 来将协程中的异常抛出
        print(loser.exception)
    

    参考:

    百度
    廖雪峰 gevent
    Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)
    gevent:轻松异步 I/O
    基于协程的Python网络库gevent介绍

    相关文章

      网友评论

          本文标题:协程库 gevent

          本文链接:https://www.haomeiwen.com/subject/pwyxxftx.html