本网站可以通过分类标签帮助你快速筛选出你想看的文章,记住地址:www.Facec.cc

为什么协程(gorutine)比线程(thread)快

最近渐渐深入golang,昨天听老师讲的深有感触,今天赶紧review一下。
为什么协程(gorutine)比线程(thread)快?

一、go协程比线程占用内存少

  • 线程是内核对外提供的服务,应用程序可以通过系统调用让内核启动线程,由内核来负责线程调度和切换。
  • golang 是自己实现的 MPG并发模型实现,协程直接的切换在用户态
    执行go协程只需要极少的栈内存(大概是4~5KB),默认情况下,线程栈的大小为1MB。
  
    goroutine就是一段代码,以及在堆上为其分配的一个堆栈。非常廉价,可以很轻松的创建上万个goroutine,它并不是被操作系统所调度执行。


二、协程之间的切换 成本开销小

    因为线程是内核级别,通过系统调用的方式切换线程。线程在等待IO操作时线程变为unrunnable状态会触发上下文切换, CPU需要记录线程的现场状态,然后把CPU分配给其他线程运行,在CPU访问内存时,会有一份虚拟地址到物理地址的缓存TLB,线程直接的切换会每次进行刷新该表

    go协程也叫用户态线程,协程之间的切换发生在用户态。在用户态没有时钟中断,系统调用等机制,因此效率高

线程每次进行切换,TLB都要进行一次刷新
image.png



三、总结

1、减少了线程切换的成本。Java 中的线程,不管是创建还是切换,都需要较高的成本。子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。这也就是说,协程的效率比较高。

2、协程的第二大优势就是,不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

3、协程更轻量级。创建一个线程栈大概需要 1M 左右,而协程栈大概只需要几 K 或者几十 K。

# linux  

评论