最近看了很多有关协程的介绍,今天在这里总结一下。
一提到协程,我们首先想到的还是它和例程,线程等概念的关系。首先我们来说说例程。例程有点类似于函数,但是它包含的内容
会更多一些操作系统的API或者服务等等,C语言提供的标准库函数其实也是例程。简单来说,一个子例程就是一次函数调用。
而协程,顾名思义就是“协作的例程”,它在1963年首次被提出,并且实现。它和传统的线程不同,线程实现的系统被称为抢占式任务。
而协程实现的系统被称为协作式任务系统。线程在运行时需要操作系统来调度,休眠或者挂起等等,需要上下文切换等系统开销,而且还
需要有同步机制。而协程的调度是程序自行管理的,不需要同步机制,协程之间的切换只涉及到控制权的交换,相比于线程,协程的运行
速度要快很多。
通俗的来说,一个子例程就是一次子函数的调用,例程只有一个调用入口,返回之后就结束了。举个例子,main函数调用function1,
function1调用function2,这样就形成了父子关系,function2执行结束后函数栈回退,然后function1继续执行,结束后函数栈再回退,最后
main继续执行直到函数栈回退至退出程序。但是协程运行时,每个协程都拥有自己的栈和控制块,某个协程挂起前,该协程的non-volatile
寄存器值被保存在该协程对应的控制块中。新激活协程在恢复前,它的控制块中的寄存器值被恢复到CPU的寄存器中。这样在协程相互
切换时,就不需要维护上下文,减少了操作系统的开销,运行速度会更快。
协程分为对称协程和非对称协程(又叫半对称协程)
非对称协程知道自己的调度者是谁,它在挂起时会把自己的控制权转给其调度者,然后调度者再根据规则调用其他的非对称协程
进行工作。而对称协程的控制权直接在对称协程之间传递,即对称协程在挂起时主动指明另一个对称协程来接收控制权。
还有一点要注意,协程是第一类对象,它可以作为参数传递,由参数创建并返回,这样可以给开发者提供很大的方便。
最后总结一下:
协程相对于例程:每个协程都有自己的栈和控制块,由程序自行完成协程之间的切换
协程相对于线程:协程的切换完全由程序员自行管理,极大的减少进程/线程之间的因为维护上下文而进行的系统开销,运行速度
更快。但是由于其切换时完全由程序员自行控制的,所以对程序员的要求比较高,同时协程也无法使用标准线程的功能。一句话:线程
是由操作系统控制的,协程是由用户控制的,协程是用户层的线程。
以上就是今天的内容。
与您共勉!