Skip to content

Instantly share code, notes, and snippets.

@5idu
Created April 15, 2019 14:43
Show Gist options
  • Save 5idu/88ed87407516263ba282b4e926aaea79 to your computer and use it in GitHub Desktop.
Save 5idu/88ed87407516263ba282b4e926aaea79 to your computer and use it in GitHub Desktop.
goroutine小知识点
### Goroutine
一个程序运行的时候
- 一个进程 --> 多个线程
- 一个逻辑处理器(默认和当前电脑CPU数目一致)`(P)` --> 多个线程
- 一个线程`(M)`--> 多个协程
- 调度器:go运行时中的,分配goroutine给不同的逻辑处理器,等待线程处理
- 协程由go运行时实现
- 全局运行队列:所有刚创建的goroutine都会放到这里
- 本地运行队列:逻辑处理器的goroutine队列`(G)`,不超过256个
**当我们创建一个goroutine后,会先存放在全局运行队列中,等待Go运行时的调度器进行调度,把他们分配给其中的一个逻辑处理器,并放到这个逻辑处理器对应的本地运行队列中,最终等着被线程执行即可**
### Go调度器
- G: goroutine,每个G都代表1个goroutine
- M: 工作线程,是Go语言定义出来在用户层面描述系统线程的对象 ,每个M代表一个系统线程
- P: 处理器,它包含了运行Go代码的资源
**3者的简要关系是P拥有G,M必须和一个P关联才能运行P拥有的G**
### 调度器的4个部分
- 全局队列(Global Queue):存放等待运行的G。
- P的本地队列:同全局队列类似,存放的也是等待运行的G,存的数量有限,不超过256个。新建G'时,G'优先加入到P的本地队列,如果队列满了,则会把本地队列中一半的G移动到全局队列。
- P列表:所有的P都在程序启动时创建,并保存在数组中,最多有GOMAXPROCS个。
- M:线程想运行任务就得获取P,从P的本地队列获取G,P队列为空时,M也会尝试从全局队列拿一批G放到P的本地队列,或从其他P的本地队列偷一半放到自己P的本地队列。M运行G,G执行之后,M会从P获取下一个G,不断重复下去。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment