为什么要有协程

大耗子 2020年12月28日 56次浏览

同步IO操作

同步IO操作相当于将所有的操作都放进了同一个流程里,如果出现阻塞行为,会导致整个程序的卡顿。客户体验极差。

异步IO操作

  • 异步IO操作相当于将读写事件放到分支线程中去执行,当执行完毕去通知主线程就可以了,此时主线程可以安心的管理他的事件等操作,而不用浪费事件做这种花费事件很长的读写操作,提升CPU的运行效率,毕竟总所周知内存操作比cpu操作的速度慢了不是一个数量级。
  • 虽然理论上,可以每个客户端分配一个线程,但是如果在大并发的条件下,电脑根本顶不住这样的调度消耗。毕竟线程需要做资源共享,必然需要锁定临界资源,线程的调度就要消耗大量的时间。也就是所谓的感觉好卡。

进程

进程说白了就是一个资源的集合,里面有数据资源,文件资源,独立的内存空间。每多一个进程就多一份资源。在使用fork函数生成子进程时候,也是对父进程数据的一份拷贝,数据虽然一样,但资源是不共享的。不可能去用进程做大并发,进程台消耗资源了。

线程

  • 线程是从属于进程,是进程的实际执行者,在一个进程中,必定有用一个主线程,也可以拥有很多的子线程。线程拥有自己的栈空间,但是资源使用进程的资源,所以同一个进程的所有进程共享该进程的资源。线程本身没有资源。对操作系统来说,线程是最小的执行单元,进程是最小的资源管理单元。

线程的痛点

1.涉及到同步锁。
2.涉及到线程阻塞状态和可运行状态之间的切换。
3.涉及到线程上下文的切换。
以上涉及到的任何一点,都是非常耗费性能的操作。

协程

  • 协程是一种比线程更加轻量级的存在,正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
  • 由于协程是在用户态执行,所以协程是完全受程序控制,而不是内核控制,这样就减少了大量的线程切换造成的资源浪费。
  • 在执行时候,如果没有事件,编写的协程完全可以不调度,知道有对应的事件后,切换对应协程的上下文,把异步的操作变成了同步的写法。从代码上看是同步的写法,但实际的运行却是异步的。即有了线程了长处,还规避了缺点,让代码的可维护性变得更好。

协程的是上下文切换

说白了,在只需要切换对应的cpu寄存器数值就可以了,所以在协程调度的时候,其实就是做的寄存器变量的备份与覆盖。

协程的调度

在程序中,需要调度的时候,调用对应语言中的resume,将对应协程的寄存器数值切换,即可运行,在调度完成后,调用yield恢复调度器的运行。