😥 整理不易,此资源只针对正式星主开放,
还请入驻星球后再来观看。

GOLANG ROADMAP

阅读模式

  • 沉浸
  • 自动
  • 日常
首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
author-avatar

GOLANG ROADMAP


首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
  • Go真实面试题汇总系列

    • 《调度模型篇》
  • 宝典内容

    • 5.Go的GMP模型?
    • 22. 讲一讲 GMP 模型
    • 42. gmp当一个g堵塞时,g、m、p会发生什么
    • 63. golang并发模型
    • 64. golang gmp模型,全局队列中的G会不会饥饿,为什么?P的数量是多少?能修改吗?M的数量是多少?
    • 67. 服务器能开多少个M由什么决定
    • 68. 服务器能开多少个P由什么决定
    • 69. M和P是怎么样的关系
    • 70. 同时启动了一万个G,如何调度?
    • 99. P和M的数量一定是1:1吗?如果一个G阻塞了会怎么样?
    • 112. 看你会golang,讲下go的协程模型?(GPM模型)
    • 121. GMP中,M的数量怎么控制,P呢?
    • 129. 知道go的抢占式调度吗?goroutine泄漏?
    • 162. 为什么 GPM 模型会更快
    • 165. golang怎么操作内核线程
    • 174. 为什么P的local queue可无锁访问,任务窃取的时候要加锁吗?
    • 199. GPM调度模型
    • 224. 一个协程挂起换入另外一个协程是什么过程?
    • 229. go语言中的GMP、defer、匿名defer函数、defer执行流程
    • 234. 协程底层怎么实现?
    • 235. go的调度
    • 282. GMP并发模型 goroutine切换的时候上下文环境放在哪里
    • 285. golang的MPG模型,goroutine和线程的区别
    • 344. golang调度能不能不要p
    • 353. 介绍go语言的gmp协程调度模
    • 396. Go如何调度,假设4核的cpu应该有几个线程或者说有几个M,那能有几个groutinue,groutinue数量的上限是多少?
    • 402. gmp模型中一定要有p吗
    • 403. 了解gmp模型的全局队列和本地队列吗
    • 428. go调度中阻塞都有那些方式
    • 434. gmp具体的调度策略

😥 整理不易,此资源只针对正式星主开放,
还请入驻星球后再来观看。

224. 一个协程挂起换入另外一个协程是什么过程?


企业题库解析小组

题目序号:(2481)

题目来源:腾讯

频次:1

答案1:(李好)

​ 对于进程、线程,都是有内核进行调度,有CPU时间片的概念,进行抢占式调度。协程,又称微线程,纤程。英文名Coroutine。协程的调用有点类似子程序,如程序A调用了子程序B,子程序B调用了子程序C,当子程序C结束了返回子程序B继续执行之后的逻辑,当子程序B运行结束了返回程序A,直到程序A运行结束。但是和子程序相比,协程有挂起的概念,协程可以挂起跳转执行其他协程,合适的时机再跳转回来。

​ 本质上goroutine就是协程,但是完全运行在用户态,采用了MPG模型:

M:内核级线程

G:代表一个goroutine

P:Processor,处理器,用来管理和执行goroutine的。

​ G-M-P三者的关系与特点:

  • P的个数取决于设置的GOMAXPROCS,go新版本默认使用最大内核数,比如你有8核处理器,那么P的数量就是8
  • M的数量和P不一定匹配,可以设置很多M,M和P绑定后才可运行,多余的M处于休眠状态。
  • P包含一个LRQ(Local Run Queue)本地运行队列,这里面保存着P需要执行的协程G的队列
  • 除了每个P自身保存的G的队列外,调度器还拥有一个全局的G队列GRQ(Global Run Queue),这个队列存储的是所有未分配的协程G。

假设主机是单核的,那么协程运行图是这样:

  • 红色部分表示挂起和休眠,黄色部分表示准备就绪等待运行,绿色部分表示正在运行。
  • 主机是单核的所以只有一个处理器P,但是系统初始化了两个线程M0和M1,处理器P优先绑定了M0线程,M1进入休眠状态。
  • P的LRQ队列里有G1,G2,G3等待处理。P目前正在处理G0,全局等待队列GRQ里保存着G4,G5,表示这两个协程还未分配给P。
  • 如果G0在短时间内处理完,P就会从LRQ中取出G1继续处理。并且将GRQ全局队列中的部分协程加入LRQ中。
  • 假设现在G1处理速度很慢,系统就会让M0线程休眠,挂起协程G1,唤醒线程M1进行处理其他的协程。这里M1会将M0未处理的协程取走处理。
  • 等到M1协程队列中所有协程处理完再次唤醒M0,或者M1处理某个协程时间较长被挂起,M0也会被唤醒。

如果处理器是多核,就会运行多个P和M。

  • M0和M1分别运行在不同的内核中,M0处理G1,G2,G3,M1处理G4,G5,G6。
  • 协程挂起的原理跟单核是一致的。
  • 当M0处理完所有的协程,而M1还未处理完,M0会取走M1的一半数量未处理的协程。