发电机是否不如“真正的”协同程序?

时间:2014-02-05 17:55:10

标签: java python lua coroutine

我想知道在扩展时通常称为生成器之间是否存在功能差异,或者在跨越多个堆栈帧和协同程序时使用它们是否仍然存在功能差异,因为它们是由某些语言提供的本身。

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

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

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

1 个答案:

答案 0 :(得分:0)

我使用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上使用它来:

  • 回应按钮
  • 超时后关闭背光
  • 滚动长文
  • 移动电机
  • 发送串口命令

开始时有点复杂,知道将收益率和诸如此类的东西放在哪里,但一旦出现就看起来相当合理。没有线程也没有多进程,因此您无法获得这种效率。但你确实获得了独立的功能,这些功能都可以访问与其他功能相同的数据,所有功能都以循环方式运行