golang的 GMP模型
文章目录
golang GMP模型
一个进程 可以有多个线程 ,每个线程 有多个协程
协程和线程的关系
N:M原理
一个协程可以挂到不同的线程上面去,所以是 N:M
每个协程可以被不同的线程去执行调度,所以 一个协程 可以属于N个线程, 一个线程 也可以调度 M 个协程,所以是 N:M
关系
一个协程 内存只是占用几个 kb, 一个线程 java里面 占用 1MB ,
使用协程的话,砍掉了很多不必要的内存空间,调度更加灵活了。
调度器策略
可视化 GMP编程
通过 go tool trace 工具可以打开 trace 文件
工作窃取算法
整个流程就是 M 线程 如果空闲,先去其他的 线程的 任务队列里面偷任务来执行【工作窃取算法】, 如果偷不到其他的队列的任务,再从全局队列中取出 groutine 来执行。
因为 如果都从全局队列中拿,会占用锁,所以从其他线程的本地队列中 获取 会比较好。
大致流程
GMP调度流程大致如下:
- 线程M想运行任务就需得获取 P,即与P关联。
- 然而 P 的本地队列(LRQ)获取 G
- 若LRQ中没有可运行的G,M 会尝试从全局队列(GRQ)拿一批G放到P的本地队列,
- 若全局队列也未找到可运行的G时候,M会随机从其他 P 的本地队列偷一半放到自己 P 的本地队列。
- 拿到可运行的G之后,M 运行 G,G 执行之后,M 会从 P 获取下一个 G,不断重复下去。
文章作者 LYR
上次更新 2021-08-14