一般来说,线程的进程的最小执行单元,被操作系统统一调度。为了提升进程的并发处理能力,可以采用多线程的方式。但是随着线程数量的增加,线程本身带来的开销变得不可忽视,特别是在大规模并发系统下线程频繁切换场景。线程的开销大体现在如下两点:
为了解决以上线程的弊端,同时满足大规模并发的要求,协程(coroutine)的概念应运而生,相比于线程,协程则轻量得多:
协程(Goroutine)依靠线程调度,而这些线程则称为协程调度器。在一个进程中会同时存在多个协程,而调度线程也有多个,协程和线程形成多对多(M : N)的关系模型。每个调度线程都是在周而复始的调度协程,其工作过程可以用以下伪代码来简单概括:
1 | //线程执行函数 |
每一个调度线程都负责调度一组协程,在每一个调度循环中,线程获取一个可运行的协程,并调度该协程。当协程调度完(调度时间片到达,长时间阻塞,协程退出等),则保存协程状态,并执行下一个调度过程。
线程被CPU调度,相当于将CPU执行时间切分成若干时间片分配给不同的线程;协程被线程调度,则进一步切分线程的执行时间。不管是线程还是协程,都是一种逻辑概念,本质上是记录程序运行上下文的一种结构体,通过一种调度机制,被挂载到CPU上执行,并在执行过程中更新上下文。