[go协程详解 1| 青训营笔记 ]

96 阅读2分钟

go协程

❤ go的协程是一个复杂的模块,它区别于其他语言的线程和进程,独立出一种新的资源管理和调度形式。下面用浅显的话分析一下协程。

1.产生背景

✔在了解go协程之前需要先讲一讲为什么会出现协程。正所谓有需求才会产生解决方案,不然就是空车独行毫无意义。

1.1线程池

对于高并发的业务场景中,我们需要进行线程池的创建,经典线程池包括任务队列,线程池。线程池从任务队列中进行任务调度,获取任务进行处理。线程池会预先创建一定量的线程。这样有助于提高效率。

经典线程池如下所示

image.png

1.2线程池瓶颈

在经典线程池中会有一种问题,当线程所执行的任务进行阻塞的系统调用时,此线程会被阻塞,此时工作线程worker就会减少,线程池对于任务队列的消费能力减弱。

当大量线程处于阻塞状态时,任务队列就会产生堆积,cpu的利用率可能会下降。

解决这个问题的方法是增加线程池的最大数量,但是最大数量的增加就意味着线程对cpu的抢占。一定程度上会造成消费能力下降。

这就是问题的产生,于是就产生了go协程来解决这个问题。

2.Goroutine调度器

线程过多,意味着操作系统会不断的进行线程调度,就会跟进程调度一样花费更多的资源。Go中就提供了一种机制,自我进行线程的调用。而进行线程调度的东西就是Goroutine调度器。

Goroutine主要概念如下:

  • G(Goroutine): 即Go协程,每个go关键字都会创建一个协程。
  • M(Machine): 工作线程,在Go中称为Machine。
  • P(Processor): 处理器(Go中定义的一个摡念,不是指CPU),包含运行Go代码的必要资源,也有调度goroutine的能力。

M必须拥有P才可以执行G中的代码,P含有一个包含多个G的队列,P可以调度G交由M执行。其关系如下图所示: