Greenlet API的纯python实现

发布于 2021-01-29 15:09:22

gevent和eventlet将greenlet包用于异步IO。它被编写为C扩展,因此不适用于Jython或IronPython。如果性能无关紧要,那么在纯Python中实现greenlet
API的最简单方法是什么。

一个简单的例子:

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
    print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

应该打印12、56、34(而不是78)。

关注者
0
被浏览
67
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    自2.5版以来,内置于标准Python发行版中的协同例程可以实现这种目的。如果IronPython和co完全兼容所有Python
    2.5功能(我相信它们是),那么您应该可以使用此惯用法。

    有关如何使用它们的更多信息,请参见这篇文章:)特别地,您将对PDF感兴趣,在PDF中,作者仅使用纯Python构建系统,该系统提供与无堆栈Python或Greenlet模块类似的功能。

    您可能还需要寻找GogenKamelia的想法:这些项目都具有纯python协程实现,您可以采用它们或将其用作自己实现的参考。请看此页面,以轻松地介绍cogen做事方式。

    请注意,此处的协同例程实现与greenlet实现之间存在一些差异。纯粹的python实现都使用某种外部调度程序,但思想本质上是相同的:它们为您提供了一种运行轻量级合作任务的方式,而无需求助于线程。此外,上面链接的两个框架都非常类似于异步IO
    greenlet

    这是您发布但使用重写的示例cogen

    from cogen.core.coroutines import coroutine
    from cogen.core.schedulers import Scheduler
    from cogen.core import events
    
    @coroutine
    def test1():
        print 12
        yield events.AddCoro(test2)
        yield events.WaitForSignal(test1)
        print 34
    
    @coroutine
    def test2():
        print 56
        yield events.Signal(test1)
        yield events.WaitForSignal(test2)
        print 78
    
    sched = Scheduler()
    sched.add(test1)
    sched.run()
    
    >>> 12
    >>> 56
    >>> 34
    

    它比greenlet版本要明确一些(例如,WaitForSignal用于显式创建恢复点),但是您应该了解一般概念。

    编辑:我刚刚确认这可以使用jython

    KidA% jython test.py 
    12
    56
    34
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看