← 返回目录

协程优势及其通信方式

第 28 / 29 卷日期:

协程优势及其通信方式

协程相当于是用户态的线程

进程切换消耗资源很大,且进程间通信较复杂,于是有了线程

每个线程都有自己的堆栈和寄存器,并共享所属进程内的其他资源,因此可以方便地实现线程切换和通信,但是也由于多个线程共享地址空间,任何一个线程出错时,同进程内的所有进程都会崩溃

但是线程也难以实现高并发,因为:

  1. 线程消耗的内存还是很多,在linux系统中高达8MB,同时为了解决线程申请堆内存时互相竞争的问题,每个

线程预先在这个空间内预分配了64MB作为堆内存池,因此没有足够的内存去开启十几万的线程实现并发

  1. 线程切换耗时:线程的切换是由内核控制的,因此当线程繁多的时候,线程间的切换会消耗cpu很多的计算能

力

而协程使本来由内核实现的切换工作,交给了用户态的代码完成

通常创建协程时,会从进程的堆上分配一段内存作为协程的栈,线程的栈有8M,而协程的栈只有几十K

每个协程都有独立的栈,在go语言中,运行时系统会帮助自动创建和销毁系统线程,而对应的用户级协程是架设在线程之上的,用户级协程的创建销毁和调度都完全由程序实现和处理,而不用经过操作系统去做,速度会很快,很

容易控制和灵活

因此总结下来,协程的优势有:

  1. 节省cpu,避免系统内核级的线程频繁切换造成的cpu资源浪费
  2. 节约内存
  3. 稳定性
  4. 开发效率,协程是合作式的,可以方便地将一些操作异步化

Go中协程的通信方式

可以通过共享内存(变量)加锁的方式来进行通信,但是维护成本较高

官方推荐通过channel进行通信:

channel的主要功能是:

  1. 作为队列存储数据
  2. 阻塞和唤醒goroutine

select:

select搭配channel使用,其机制是监听多个channel,每一个case都是一个事件,一旦某个事件就绪(chan没有堵塞),就会从这些就绪事件中随机选择一个去执行,default用于所有chan都堵塞的情况执行

使用channel进行控制子goroutine的机制可以总结为:

循环监听一个channel,在循环中可以放select来监听channel达到通知子goroutine的效果,再配合Waitgroup,主进程可以等待所有协程结束后再自己退出;这样就通过channel实现了优雅控制goroutine并发的开始和结束

全站分卷索引 · 29 卷
  1. 1代码随想录知识星球精华(最强八股文)第五版(Go篇))
  2. 2Go string 和 []byte 的区别
  3. 3数组和切片的区别
  4. 4扩容前后的Slice是一样的吗
  5. 5Go语言map是有序的还是无序的, 为什么
  6. 6go里面的map是并发安全的吗?如何并发安全
  7. 7Go 的错误处理和 Java 的异常处理对比
  8. 8介绍一下panic和recover
  9. 9什么是defer?有什么作用
  10. 10Go并发
  11. 11进程、线程的区别
  12. 12什么是go runtine
  13. 13Go语言中的Channel是什么, 有哪些用途,如何处理阻塞
  14. 14什么是互斥锁(mutex)?在什么情况下会用到它们?
  15. 15Mutex有几种模式
  16. 16goroutine什么情况会发生内存泄漏?如何避免。
  17. 17Go语言中GC的流程是什么
  18. 18Go 中的内存逃逸现象是什么?
  19. 19CAP 理论,为什么不能同时满足
  20. 20说一下 Gin 的路由怎么实现的
  21. 21简述slice的底层原理,和数组的区别是什么
  22. 22defer底层原理
  23. 23侵入式和非侵入式的区别
  24. 24goroutine与线程的区别
  25. 25goroutine在什么情况下会被挂起呢?
  26. 26GC(垃圾回收)原理 1.5版本
  27. 27简述Go的垃圾回收机制
  28. 28协程优势及其通信方式
  29. 29Go的内存对齐