惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
IT之家
IT之家
博客园_首页
博客园 - 【当耐特】
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
G
Google Developers Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Recent Announcements
Recent Announcements
F
Fortinet All Blogs
GbyAI
GbyAI
腾讯CDC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
H
Help Net Security
T
Tailwind CSS Blog
B
Blog RSS Feed
Martin Fowler
Martin Fowler
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
博客园 - 叶小钗
雷峰网
雷峰网
量子位

博客园 - dribs

PD分离 基于GPT2训练构建医疗问诊机器人 物流行业信息咨询智能问答系统 day8 golang-chan-协程-定时器-锁-等待组 golang面试题单向链表和双向链表 golang 自行实现一个base64加密 golang标准库log+第三方zerolog golang标准库序列化反序列化 json + 第三方msgpack golang 标准库 目录操作 golang-day1 进制 golang-标准库文件操作 golang-标准库时间time day6 golang-标准库(随时更新) golang--day5结构体+结构体排序+错误处理+结构体和接口实现面向对象的例子 golang-day4函数 ceph warn oldest client/flush tid ceph 扩容后healt-error k8s系列---pod手动驱逐 k8s系列---Chart(下)
day7 golang GMP
dribs · 2023-04-06 · via 博客园 - dribs

2023-04-06 20:44  dribs  阅读(54)  评论()    收藏  举报

大名鼎鼎的GMP模型 需要自行学习的知识:进程、线程、协程、多线程、线程池、io多路复用,内核态用户态,,同步阻塞异步非阻塞等等相关知识

代码是在线程中运行的,协程也是,所以当协程阻塞的时候该线程也阻塞了,其他任务就无法调度了,该线程就死了。

如何解决,那就需要让协程自由的在线程中移动,当阻塞的时候把他扔一边,把其他协程绑定到该线程上让他继续干活。

等刚才阻塞的任务又活过来的时候,在把这个协程任务和线程绑定起来,继续干活。

理解了上面这些就可以简单看GMP模型了

G:goroutine  任务函数包装成go协程,也就是go协程,他存储了协程的执行栈信息、状态、任务函数等,初始栈大小2-4K

M:machine Thread,对系统线程抽象封装,所有代码最终都要在系统线程上运行

P:Processor 虚拟处理器,默认为cpu核心数,p的数量决定着最大可并行的G的数量;P有自己的队列长度LRQ长度256,这里放的是待执行的G;M和P绑定在一起,这样P队列中的G才能真正的在线程上执行

下面以topgoer.com里的图为例解释

1、通过go 关键字创建goroutine,把创建好的G1-Gn放到P的本地队列,如果LRQ满了超过256,则放到GRQ全局队列

2、P1和M1 绑定,M1从P1的LRQ中请求G,如果没有则从GRQ中请求,如果还没有就偷其他P中的G到自己的LRQ中,最后在M1上执行,执行完解绑,继续绑定拿G执行。

3、如果进入chanel 互斥锁阻塞,解绑,继续拿G绑定执行,如果g1被唤醒就把g1的任务放入唤醒的自己的LRQ中,如果队列满就把g1和LRQ中的一半仍到GRQ中

4、如果遇到同步阻塞,g1和m1都阻塞,那就把m1和p1解绑,p1在从休眠里面拿一个m和自己绑定(没有就创建),获取p1里的其他g继续在m上跑;如果m1阻塞结束,优先和p1绑定,如果没闲着的p,g1进GRQ,m1进休眠队列