跳到主要内容

6、协程

一、什么是协程?

【百度百科】协程与子例程一样,协程(coroutine)也是一种程序组件。相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。

协程更适合于用来实现彼此熟悉的程序组件,如合作式多任务,迭代器,无限列表和管道。 协程的概念1963年就被提出来了。但直到最近几年才在某些语言(如Lua)中得到广泛应用。现在在面试的时候,有可能会被问到。笔者就有这样的经历。

协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用

一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。

二、各大语言对协程的支持程度

1.Lua从5.0版开始支持协程的概念,极大的扩展了Lua的能力。

Lua的协程通过扩展库coroutine来实现,其中的所有函数如下(具体可以参考Lua的官方manual):

coroutine.create
coroutine.resume
coroutine.running
coroutine.status
coroutine.wrap
coroutine.yield

当前运行的代码可以看作运行在主协程中(就像C程序的main运行在主线程中),通过create可以创建一个协程,resume以运行此协程,直到新协程调用yield程序才能返回到”主协程“中运行。

协程通常是纯软件实现的多任务,与CPU和操作系统通常没有关系,所以没有理论上限。唯一的缺点似乎就是:它不能同时将 CPU 的多个核用上。但对 lua 来说这通常不是问题,因为一个宿主程序里面是可以允许有多个 lua 状态机的,开多个线程或进程,然后每个核开一个 lua 状态机即可。