Created
April 15, 2019 14:43
-
-
Save 5idu/88ed87407516263ba282b4e926aaea79 to your computer and use it in GitHub Desktop.
goroutine小知识点
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### 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