协程就是goto吗?两者有何异同?
拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...
goto是在同一个函数中跳转,协程应该类似于setjump和longjump,这个是在不同函数间跳转。
setjump
longjump
这么说不准确,应该说协程一个主要功能就是跨函数的goto,当然,在需要时还能goto回来,这一点更像函数调用。
协程是一种计算机程序设计的组件,它范化了子例程的概念.协程非常适合用于实现一些有用的程序组件例如,协作式多任务,异常处理,事件循环,迭代器,无限链表和管道等.
下面对比一般的子例程和协程:
子例程的起始处是惟一的入口点,一旦退出即完成了子例程的执行,子例程的一个实例只会返回一次。
子程序总是在它的开始处被启动,它通常是一个固定的位置.共行程序总是在它上次结束处的下一位置被启动.
协程可以通过yield来调用其它协程。通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的。
子例程容易实现于堆栈之上,因为子例程将调用的其他子例程作为下级。相反地,协程对等地调用其他协程,最好的实现是用 continuations(由有垃圾回收的堆实现)以跟踪控制流程。
Marlin对coroutine的特性描述如下:
coroutine中的局部变量在后续调用中保持有效.
当控制离开的时候coroutine被挂起,将控制权交还给它的时候在它挂起的地方继续执行.
协程的分类
1)通过控制转移机制分类:对称协程与非对称协程
非对称协程(asymmetric),或称为半对称协程(semi-symmetric)或半协程(semi-coroutines).非对称协程可以被看作是调用者的从属过程,它们之间的关系跟调用和被调用例程的关系类似.
对称协程只提供了一种控制转移机制:将执行流程交给指定的协程.因为对称协程之间可以互相转移执行流程,所以它们之间的关系 就像在同一个层级.
2) 协程是否一级类型(first-class)
3) 是否有完整的栈
有完整栈的协程,允许协程在最内层的函数中挂起自己.以后此协程被resume将会从它被挂起的 地方继续执行.
没有完整栈的协程,例如python的generator,则只能在generator的主body中被挂起.
有完整栈的协程可以用于实现用户级多任务而没有完整栈的协程则不行.
协程的关键字是yield,个人觉得含义应该是: 中断执行,返回数据.再次调用,回到断点,恢复执行. yield 等价于 return 并且 goto breakpoint.
goto是在同一个函数中跳转,协程应该类似于
setjump
和longjump
,这个是在不同函数间跳转。这么说不准确,应该说协程一个主要功能就是跨函数的goto,当然,在需要时还能goto回来,这一点更像函数调用。
协程是一种计算机程序设计的组件,它范化了子例程的概念.协程非常适合用于实现一些有用的程序组件例如,协作式多任务,异常处理,事件循环,迭代器,无限链表和管道等.
下面对比一般的子例程和协程:
子例程的起始处是惟一的入口点,一旦退出即完成了子例程的执行,子例程的一个实例只会返回一次。
子程序总是在它的开始处被启动,它通常是一个固定的位置.共行程序总是在它上次结束处的下一位置被启动.
协程可以通过yield来调用其它协程。通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的。
子例程容易实现于堆栈之上,因为子例程将调用的其他子例程作为下级。相反地,协程对等地调用其他协程,最好的实现是用 continuations(由有垃圾回收的堆实现)以跟踪控制流程。
Marlin对coroutine的特性描述如下:
coroutine中的局部变量在后续调用中保持有效.
当控制离开的时候coroutine被挂起,将控制权交还给它的时候在它挂起的地方继续执行.
协程的分类
1)通过控制转移机制分类:对称协程与非对称协程
非对称协程(asymmetric),或称为半对称协程(semi-symmetric)或半协程(semi-coroutines).非对称协程可以被看作是调用者的从属过程,它们之间的关系跟调用和被调用例程的关系类似.
对称协程只提供了一种控制转移机制:将执行流程交给指定的协程.因为对称协程之间可以互相转移执行流程,所以它们之间的关系 就像在同一个层级.
2) 协程是否一级类型(first-class)
3) 是否有完整的栈
有完整栈的协程,允许协程在最内层的函数中挂起自己.以后此协程被resume将会从它被挂起的 地方继续执行.
没有完整栈的协程,例如python的generator,则只能在generator的主body中被挂起.
有完整栈的协程可以用于实现用户级多任务而没有完整栈的协程则不行.
协程的关键字是yield,个人觉得含义应该是:
中断执行,返回数据.再次调用,回到断点,恢复执行.
yield 等价于 return 并且 goto breakpoint.