Goroutine的调度分析(二)
来源:互联网 发布:网络综艺访谈节目 编辑:程序博客网 时间:2024/06/06 06:43
Go 是用C写的,对于Goruntime,主要有三个数据将结构(其实是4个,后面会讲)支持着goruntime记录着所有的信息以及调度。
G
G数据结构代表一个goroutine。他保存着goroutine的栈和当前的状态。当然也保存着它将要运行的code的一些相关信息。如下图所示
M
M数据结构代表系统线程,它有保存全局goroutine队列的指针,当前运行G的指针,它自己的cache.
SCHED
Sched数据结构是一个单个的,全局的数据结构,它记录着不同的G和M的队列,以及一些其他保证调度器可以有序跑起来的信息。有两个G队列,一个是当前可以跑的goroutine的队列,另外一个是空闲的G队列。只有一个跟M有关系的G队列并且是调度器保持的。M队列中M是空闲的并且是waiting to work的状态。Sche的数据结构如下图
runtime一开始需要执行若干个G。一个用来垃圾回收,一个用来调度,一个代表着用户的G code。初始化的时候,一个M被创建,用来启动runtime。当程序跑起来的时候,很多G可能会被用户程序创建,所有有可能需要更多的M来运行这些用户的G。所以runtime可能会提供更多的线程(最多有GOMAXPROCS个激活线程)
因为M代表着线程,并且M是用来执行goroutine的。所以一个当前没有相关G的线程会从全局队列中取一个G并且执行这个G。如果这个G要求M阻塞,例如进入了系统调用没那么其他的M就会从全局M队列中唤醒。这样做事为了阻塞的M上的goroutine仍然可以被执行。
系统调用强制线程阻塞,阻塞的时间是系统调用的执行时间。如果一个因为G因为系统调用而阻塞,那么执行这个G的M就不能执行其他的G直到系统调用返回。channel通信不会导致M阻塞。系统不知道channel通信,复杂的channel完全由runtime来控制。如果一个goroutine进入了channel call,它可能会blocak,但是执行这个G的goroutine并不会被阻塞。这种情况下,G的状态会被设置成waiting并且M会运行其他的goroutine知道channel 通信完成。这时候G的当前状态会被重新设置为runnable并且会被等待运行。
- Goroutine的调度分析(二)
- Goroutine的调度分析(一)
- Goroutine调度分析(三)
- Goroutine 的调度
- golang的goroutine调度机制
- go语言的goroutine调度机制
- goroutine与调度器
- goroutine与调度器
- goroutine与调度器
- Goroutine 调度模型猜想
- go-goroutine 调度
- [转]Golang中goroutine的调度器详解
- Linux内核分析(二)之简单的进程调度
- Linux内核分析(二)之简单的进程调度
- Golang1.7 Goroutine源码分析
- goroutine的一种使用方法
- 无辜的goroutine
- go的goroutine问题
- 数据结构循环链表与双链表实验
- linux matlab2016b 安装
- redis 性能相关方面
- 操作系统-PV操作
- [PAT乙] 1014. 福尔摩斯的约会 (20)
- Goroutine的调度分析(二)
- android NDK--C 调用java
- 某集训记录
- 高并发秒杀系统实现和优化分析(行级锁优化和具体过程优化)
- cenos7安装elasticsearch5.5.2
- redis 网络分区
- Mysql课后思考题
- 栈的应用2--通用括号平衡
- Mysql综合案例