0

我真的很佩服 Stackless Python 的功能,我一直在寻找一种方法来模拟它的语法,同时仍然使用标准的 Python 3 解释器。Alex J. Champandard 在 gamedev 博客中的一篇文章使 greenlet 库看起来可以提供此功能。我稍微修改了他的代码,但我能想到的最好的临时 tasklet 包装器是一个在变量中包含一个 greenlet 的类,如下所示:

class tasklet(): 
        def __init__(self,function=None,*variables):
                global _scheduled
                self.greenlet = greenlet.greenlet(function,None)
                self.functioncall = function # Redundant backup
                self.variables = variables
                _scheduled.append(self)
                self.blocked = False

switch()然后,该函数通过在调用其方法时将变量传递给 greenlet 来模拟 Stackless 的调度。

到目前为止,这似乎可行,但我希望能够以原始的 Stackless 语法调用 tasklet,例如tasklet(function)(*args),与当前的语法相反tasklet(function,*args)。我不确定在哪里查看文档以了解如何完成此操作。这是否可能,或者它是 Stackless 对解释器的更改的一部分?

4

1 回答 1

1

根据2010-01-08 的这篇文章(带有固定链接):

Stackless Python是 Python 语言(及其 CPython 参考实现)的扩展版本。新功能包括轻量级协程(称为 tasklet)、使用消息传递的通信原语(称为通道)、手动和/或自动协程调度、不使用 C 堆栈 Python 函数调用,以及协程的序列化(用于在另一个进程中重新加载)。Stackless Python 不能作为 Python 扩展模块实现——CPython 编译器和解释器的核心必须打补丁。

greenlet是 CPython 的扩展模块,提供协程和低级(显式)调度。与 Stackless Python 相比,greenlet 最重要的优势是 greenlet 可以作为 Python 扩展模块实现,因此无需重新编译整个 Python 解释器即可使用 greenlet。greenlet 的缺点包括速度(Stackless Python 可以快 10%、35% 或 900%,具体取决于工作流程);如果协程相互引用,可能会导致内存泄漏;并且提供的功能是低级的(即仅手动协程调度,不提供消息传递)。

我最近开发的 Python 模块 greenstackless 提供了大部分使用 greenlet 的(高级)Stackless Python API,因此它消除了 greenlet 低级的缺点。查看 源代码一些测试(后者带有棘手的极端情况)。请注意,虽然 greenstackless 进行了一些优化,但它可能比 Stackless Python 慢得多,而且它也不能修复内存泄漏。因此不建议在生产环境中使用 greenstackless;但如果替换 Python 解释器不可行,它可以用作 Stackless Python 的临时替代品。

其他一些使用 greenlet 模拟 Stackless 的软件:

并发:不支持 stackless.main、tasklet.next、tasklet.prev、tasklet.insert、tasklet.remove、stackless.schedule_remove,不能正确发送异常。(由于缺少这些功能,它没有通过上面的单元测试。)

PyPy:不支持stackless.main、tasklet.next、tasklet.prev,没有通过上面的单元测试。

于 2014-05-12T16:06:41.383 回答