ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【GO面试精要】GMP并发模型、Goroutine

2021-04-11 15:32:38  阅读:270  来源: 互联网

标签:执行 goroutine 队列 Goroutine 调度 线程 GO GMP


GMP并发模型

进程与线程与协程goroutine

多个线程属于同一个进程并共享内存空间,线程之间的通讯基于共享的内存进行。

Go语言的调度器使用与CPU数量相等的线程来调度多个Goroutine。

为什么用Go语言?“

进程、线程存在问题:

  1. CPU高消耗
    • 切换线程上下文需要申请、销毁资源消耗时间高
  2. 内存高占用
    • 线程占用1M以上的内存空间

协程(Goroutine)的优点:

  1. 占用的内存更小(几kb)
    • 初始为2kb,如果栈空间不足则自动扩容
  2. 调度更灵活(runtime调度)
    • Go自己实现的调度器,创建和销毁的消耗非常小,是用户级。
  3. 抢占式调度(10ms)
    • 编译器插入抢占指令,函数调用时检查当前Goroutine是否发起抢占请求
  4. 1.14版本后支持基于信号的异步抢占(20ms)
    • 垃圾回收扫描栈时触发抢占调度
    • 解决抢占式调度因垃圾回收和循环长时间占用资源(无法执行抢占指令)导致程序暂停

GMP并发模型

GMP

在这里插入图片描述

图-GMP

G 需要在 M 上才能运行,M 依赖 P 提供的资源,P 则持有待运行的 G,M 与 P 的数量没有绝对关系,一个 M 阻塞,P 就会去创建或者切换另一个 M,所以,即使 P 的默认数量是 1,也有可能会创建很多个 M 出来。

G: 取 goroutine 的首字母,主要保存 goroutine 的一些状态信息以及 CPU 的一些寄存器的值

M: 取 machine 的首字母,它代表一个工作线程,或者说系统线程。G 需要调度到 M 上才能运行,M 是真正工作的人

P:取 processor 的首字母,为 M 的执行提供“上下文”,保存 M 执行 G 时的一些资源,例如本地可运行 G 队列,memeory cache 等。

你了解过GMP并发模型吗?“

GM老版调度器:

  1. 激烈的锁竞争
    • 从全局队列中获取G,需要加锁
  2. 局部性差
    • 比如当 G 中包含创建新协程的时候,M 创建了 G’,为了继续执行 G,需要把 G’交给 M’执行,也造成了很差的局部性,因为 G’和 G 是相关的,最好放在 M 上执行,而不是其他 M’。
  3. 系统开销大
    • 系统调用 (CPU 在 M 之间的切换) 导致频繁的线程阻塞和取消阻塞操作增加了系统开销。

M 想要执行、放回 G 都必须访问全局 G 队列,并且 M 有多个,即多线程访问同一资源需要加锁进行保证互斥 / 同步,所以全局 G 队列是有互斥锁进行保护的。
GM

GMP新版调度器(记忆图-GMP

  1. 解决GM老版调度器的问题

  2. M(线程):N(协程)关系

    • 创建 M 个线程(CPU 执行调度的单位),之后创建的 N 个 goroutine 都会依附在这 M 个线程上执行。

    • 在同一时刻,一个线程上只能跑一个 goroutine。当 goroutine 发生阻塞时,runtime 会把当前 goroutine 调度走,让其他 goroutine 来执行。

  3. 任务偷取(work stealing)

    • 全局队列已经没有 G,那 m 就要执行 work stealing (偷取):从其他有 G 的 P 哪里偷取一半 G 过来,放到自己的 P 本地队列
  4. 让出执行权(hand off)

    • 某个G堵塞,线程释放绑定的P,把P转移给其它空闲线程

“go func() 执行过程?”

go func

  1. go关键字创建一个goroutine入队,如果本地P队列满了则入队全局G队列
  2. 从P队列中队头的G交给M执行
  3. P有两个关键特性
    1. work stealing
    2. hand off

查看更多Github

标签:执行,goroutine,队列,Goroutine,调度,线程,GO,GMP
来源: https://blog.csdn.net/weixin_42322309/article/details/115599837

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有