什么是协程?

协程

协程(Coroutines)是一种比线程更加轻量级的存在。协程完全由程序所控制(在用户态执行),带来的好处是性能大幅度的提升。 一个操作系统中可以有多个进程;一个进程可以有多个线程;同理,一个线程可以有多个协程。

协程是一个特殊的函数,这个函数可以在某个地方挂起,并且可以重新在挂起处继续运行。 一个线程内的多个协程的运行是串行的,这点和多进程(多线程)在多核CPU上执行时是不同的。 多进程(多线程)在多核CPU上是可以并行的。当线程内的某一个协程运行时,其它协程必须挂起。

协程切换

由于协程切换是在线程内完成的,涉及到的资源比较少。不像内核级线程(进程)切换那样,上下文的内容比较多,切换代价较大。协程本身是非常轻巧的,可以简单理解为只是切换了寄存器和协程栈的内容。这样代价就非常小。

如果有不了解进程(线程)切换的,可以参考下面的资料:

深入理解Linux内核进程上下文切换

操作系统(四) – 用户级线程与核心级线程(线程的切换)

线程

协程切换的问题

实际上协程只有在等待IO的过程中才能重复利用线程,也就是说协程本质是通过多路复用来完成的。但是有个问题是,协程本身不是线程,只是一个特殊的函数,它不能被操作系统感知到(操作系统只能感知到进程和内核级线程),如果某个线程中的协程调用了阻塞IO,那么将会导致线程切换发生。因此只有协程是不够的,是无法解决问题的。还需要异步来配合协程。 因此,实际上我们可以把协程可以看做是一种用户级线程的实现。 协程+异步才能发挥出协程的最大作用

协程的使用

  • 计算型的操作,利用协程来回切换执行,没有任何意义,来回切换并保存状态 反倒会降低性能。
  • IO型的操作,利用协程在IO等待时间就去切换执行其他任务,当IO操作结束后再自动回调,那么就会大大节省资源并提供性能,从而实现异步编程(不等待任务结束就可以去执行其他代码)。

协程不是什么银弹,要注意使用场景。