线程分为用户级线程,内核级线程和轻量级线程。Linux中使用的是轻量级线程,而协程虽然是运行在线程之上,但是是run在用户空间。并且协程和线程一样,拥有自己的调度器、cpu的上下文切换等。
协程在我个人看来是一种用户级线程;
- 这是因为对于cpu有上下文的切换,而且是在用户空间的层次进行数据处理;一旦被内核的代码阻塞,是无法进行解除阻塞状态;
首先需要明确一点,协程是干嘛的,针对的事物是什么?
异步IO的效率高,是正常的,因为调用某个IO函数,也就是系统调用,根据异步IO模型中的描述,它不会被阻塞且处理完毕后会通知调用线程,也就是异步IO模型没有阻塞时间。
那么问题就来了,应该是一个什么样的逻辑处理同步IO,才能让其性能接近异步IO呢?
协程由运行体和调度器组成。
协程的运行体中保存着让出后的寄存器状态,方便于之后恢复、子过程函数和其参数、自身协程的状态、栈的大小等;
也就引出了yeild和resume这两个功能
- yeild的中文名叫让出,cpu每个时刻只能运行一个操作(),让出操作会让当前cpu的寄存器空出给其他协程运行体(函数)使用
- resume的中文名叫恢复,cpu空出后,恢复之前协程运行体(函数)执行的位置。
由于讨论的是一个线程的操作,不会出现内核切换线程的操作。
接下来要说是调度器,使用yeild和resume两个操作,进行切换协程。使用协程A->调度器->协程B这种形式的切换,而不是协程A->协程B。下图可以很好说明这个形式。
协程调度器在调度协程运行体的时候就需要维护协程所具有的状态,比如就绪、等待、睡眠。
这也就需要一些数据结构进行维护这些运行体。
至于它和reactor进行对比,它俩的性能差距不会很大。
协程相比于reactor,reactor的回调函数太过于分散,不易代码可读。
reactor其实是对事件进行一个异步的处理,于此同时也不需要看到IO处理的逻辑,只需要关注每一个事件应该怎么做。