协程
协程,又称微线程,英文名Coroutine
进程、线程、协程
进程是应用程序启动的实例,进程拥有代码和打开的文件资源、数据资源、独立的内存空间(是拥有资源的独立单位)。
线程属于进程没事程序的实际执行者,一个进程至少包含一个线程,也可以拥有更多的子线程,子线程拥有自己的栈空间。但是并不独立拥有堆、静态空间等资源。对操作系统而言,线程是最小的执行单元,进程是最小的资源管理单元,无论进程还是线程,都是由操作系统进行管理。
协程(Coroutines)是比线程更加轻量级的存在,增如一个进程可以拥有多个线程一样,一个线程可以拥有多个协程。协程是不被操作系统所管理的,而由程序完全控制,也就是在用户态完全进行。这样带来的好处是性能的大阿福提升,因为不会想线程那样切换从而消耗资源。
协程本质上是一个特殊函数,在主程序上可以进行这个函数的控制,暂停启动,但是一个线程的多个协程(函数),只能是串行的,一个协程被运行是,其他协程必须被挂起。
对比
- 协程既不是进程也不是线程,协程仅仅是一个特殊的函数,协程、进程和线程不是一个维度的。
- 一个进程可以包含多个线程,一个线程可以包含多个协程。
- 一个线程内的多个协程虽然可以切换,但是多个写成是串行执行的,只能在一个线程内执行,没法利用CPU多核的能力。
- 线程和进程一样,切换时存在上下文却换问题。
上下文切换
- 进程的切换者是操作系统,切换时机是根据操作系统自己的切换策略,用户是无法感知的。进程切换的内容包括:页全局目录、内核栈、硬件上下文,切换内容保存在内存中。进程切换过程是由“用户态到内核态,再到用户态”的方式,切换效率比较低。
- 线程的切换这是操作系统,切换时机是很具操作系统自己的切换策略,用户无法感知。线程的切换内容包括:内核栈和硬件上下文,切换内容保存在内核栈中。线程切换时由“用户态到内核态再到用户态”的方式,切换效率中等,要比进程消耗小。
- 协程的切换这是用户(程序),切换的时机是用户自己的程序逻辑所决定。协程的切换内容是硬件的上下文,切换内容保存在程序变量中(堆、栈)中。协程切换过程只有用户态,没有陷入内核,因此切换效率高。
使用环境
- 多进程:网络通信、分布式
- 多线程:I/O密集型场景,IO阻塞导致频繁切换
- 需要频繁销毁创建的有限使用线程,例如web服务器
- 需要大量计算的优先使用线程