对于线程和协程的一点理解
首先需要提到的一点就是,操作系统中有用户态和内核态的概念,进行系统调用的时候会有内核态到用户态的切换,这个开销是比较大的。
从客观上来讲,单个处理器在同一时间内本来就是无法处理多个指令的,同时执行多个任务就需要当前正在运行的任务让出处理器调度,不过这个让出操作是由线程调度器主动抢占,这种调度方式也称之为抢占式调度。假设多个正在运行的任务是毫不相关的,那这样做并没有什么问题,但是往往多个任务之间会存在依赖,操作同一份资源等问题,于是出现了同步锁,为了解决数据同步问题。
但是回到开始的问题,同步锁也是在特定是时刻强制锁定某个资源让某些任务强制退出,但是其实处理器本身就只能处理单个任务,这样做无异于脱裤子放屁。这也是多线程的模型。
回到当初的问题,既然处理器本来在同一时间就只能处理单个任务,那也不必让他们抢占了,直接排好顺序,依次进行。
也就是说,如果多个线程能够相互独立,不阻塞的情况下,抢断式的线程调度是不错的选择,它能够使得所有线程都可以被分到时间片。
但是如果多个线程之间不是相互独立的情况,可以考虑让线程自己去让出时间片,也是协程的特性。
协程是非抢占式来实现多任务,线程是抢占式实现多任务
协程需要代码编写者主动让我控制权,线程不怎么需要考虑这个问题
创建协程不太需要操作系统干预,很多编程语言都可以实现这个结构,早期的多任务都是来自于此。
后来出现的线程可以认为是一个feature 不需要考入程序在何处被插入就可以自动实现多任务,不过后来多线程的弊端也开始显现。
一般操作系统创建内核线程的数量是有限的,如果在短时间内需要响应大量请求,一般的系统是做不到的
于是,协程重新回到了程序员的视线。因为一方面,协程代码中所有让出控制权的结点都是已知的,不会存在多线程同步方面的相关问题。二方面,协程的开销非常小,成千上万个协程并发也完全没问题。
可以认为,协程一方面也是为了解决线程数量不够的问题,再发散一下,我们手动实现的线程池,某种意义上也可以认为是协程的一种,因为它只创建了有限的线程,需要多任务处理的时候,采取了手动控制他们之间的同步,也就是协同式的调度方法
上面提到的内核线程,那么相对的也有用户线程的概念,这也是
协程并不全是协同调度“
的原因,因为后面有人也把用户线程叫做协程,但是用户线程可以是抢占式的,这违背了协程这个名字我们的直觉