【问题标题】:Are generators inferior to "real" coroutines?生成器是否不如“真正的”协程?
【发布时间】:2014-03-02 07:51:29
【问题描述】:

我想知道通常称为 generator 的东西在扩展或用于跨越多个堆栈帧和协程时是否仍然存在功能差异,因为它们由某些语言提供本机。

一方面,我看到像 Python 这样的语言获得了一些特性(最后一个是 3.3 版中的 yield from),这些特性使得协同程序的大多数行为的实现变得简单,而无需提供实际的协同程序。另一方面,我看到像 KilimJavaflow 这样的项目,它们将实际的协程添加到 Java,但有一些限制,例如必须注释每个方法当协程产生已检查异常时,可能在堆栈上。

虽然这些项目都不允许 Java 程序为协程使用不同的堆栈,这正是 Lua 等语言用来实现协程的方式,但它们仍然提供了据我所知,可以从协程实现中可以预期。但这使得它们与在 Python 中使用 yield from 可以完成的事情非常相似(在实现中),我能看到的唯一区别是在 Python 中,可能产生的函数的每个调用站点都必须使用 from yield 调用而在 Java 中,可能产生的函数必须使用已检查异常进行注释,而不更改调用方法的语句。

那么协同程序之间的功能实际上是否仍然存在差异,例如它们提供的协同程序。 Lua,以及在 Python 中使用生成器和 yield from 可以做什么,或者我们应该说 Python(以及具有类似生成器实现的语言)现在提供协程?

【问题讨论】:

    标签: java python lua coroutine


    【解决方案1】:

    我使用 Python 生成器作为协程。我在任何其他环境中没有使用过协程。根据您对他们的经验水平,这可能会或可能不会回答您的问题。但这里有一些我使用的起始代码,它使用生成器以协程能力发送和接收数据,甚至不使用 Python 3 的 yield from 语法:


    一、套路:

    def sleep(timer, action=None):
        ''' wait for time to elapse past a certain timer '''
        yield   # first yield cannot accept a message
        now = then = yield
        while now - then < timer:
            now = yield
        if action:
            action()
        else:
            yield "timer finished"
    
    def buttonwait():
        ''' yields button presses '''
        yield
        yield
        while True:
            c = screen.getch()
            if c:
                yield c
            yield
    

    接下来,wait 函数管理协程,发送当前时间并监听数据

    def wait(processes):
        start = time.time()
        for process in processes:
            process.next()
            process.send(start)
        while True:
            now = time.time()
            for process in processes:
                value = process.send(now)
                if value:
                    return value
    

    最后,这些的实现:

    def main():
        processes = []
        process.append(timer(5)
        processes.append(buttonwait())
        wait(processes)
    

    我在带有 2x16 LCD 屏幕的 Raspberry Pi 上使用它来:

    • 响应按钮按下
    • 超时后关闭背光
    • 滚动长文本
    • 移动马达
    • 发送串口命令

    开始有点复杂,知道将收益放在哪里等等,但一旦它看起来就相当实用。没有线程,也没有多进程,因此您不会获得那种效率。但是您确实获得了独立的函数,它们都可以访问与其他函数相同的数据,并且都以循环方式运行

    【讨论】:

    • 感谢您的示例,但您并没有真正解决我的问题,即是否存在功能差异,例如Python 的生成器和 Lua 的协程。
    • 如果您想与 Lua 的协程进行特定比较,则应在此问题中添加 Lua 标签。我相信没有功能上的差异,但只有 Lua 开发人员的知识才能确定。同时,我的回答可能会帮助他们理解 Python,并为他们提供比较知识。
    • 你是对的,标签javapython 只提到了参数的不是很完整的协程方面的语言
    猜你喜欢
    • 1970-01-01
    • 2015-12-11
    • 2017-06-04
    • 2017-09-02
    • 1970-01-01
    • 2015-10-31
    • 2017-09-30
    • 2011-08-22
    • 2012-01-13
    相关资源
    最近更新 更多