协程3 --- golang的协程调度

文章目录

  • 单进程时代
  • 多进程/线程时代
  • 协程时代
    • 内核级线程模型(1:1)
    • 用户级线程模型(N:1)
    • 两级线程模型CMP(M:N)
    • GM模型
  • GMP模型

单进程时代

在这里插入图片描述
描述:每一个程序就是一个进程,直到程序进行完才行进行下一个进程。
问题:

  1. 单一的执行流程,计算机只能一个一个问题的处理
  2. 进程阻塞(比如说读取磁盘)带来的CPU时间浪费

多进程/线程时代

在这里插入图片描述

描述:一个程序阻塞,CPU就切换到另一个程序执行
问题:

  1. 进程/线程占用内存高
  2. 进程/线程上下文切换成本高(数量越多,切换成本也越大)
  3. 多进程/线程有 同步竞争问题(锁、资源冲突等),开发设计复杂

协程时代

描述:协程(用户态线程)绑定线程(内核态线程),CPU调度线程执行
在这里插入图片描述

内核级线程模型(1:1)

在这里插入图片描述
描述:1个用户线程对应1个内核线程,最容易实现,能够利用多核,一个线程被阻塞,不会阻塞其他线程,协程的调度都由操作系统完成。
问题:

  1. 上下文切换成本高
  2. 创建、删除和切换都由操作系统完成

用户级线程模型(N:1)

在这里插入图片描述

描述:N个用户线程对应1个内核线程,上下文切换成本低,在用户态即可完成协程切换,N个协程轮询调度。
问题:

  1. 无法利用多核
  2. 一旦协程阻塞,造成线程阻塞,线程的其它协程无法执行

两级线程模型CMP(M:N)

在这里插入图片描述
描述:M个用户线程对应N个内核线程,上下文切换成本低,一个线程被阻塞,不会阻塞其他线程。
问题:

  1. 依赖库调度器的优化

GM模型

在这里插入图片描述
描述:内核线程去go协程队列(由锁保护)获取协程,执行,将协程放回队列最后。
问题:

  1. 创建、销毁、调度G都需要每个M获取锁,这就形成了激烈的锁竞争
  2. M转移G(比如说M0执行G1的时候,G1创建了一个G2,G2被放进全局队列可能就会在M1执行,会转移局部性差)会造成延迟和额外的系统负载。
  3. 系统调用(CPU在M之间的切换)导致频繁的线程阻塞和取消阻塞操作增加了系统开销。

GMP模型

在这里插入图片描述

  • G(Goroutine)
    代表Go协程Goroutine,存储了Goroutine的执行栈信息、Goroutine状态以及Goroutine的任务函数等。G的数量无限制,理论上只受内存的影响,创建一个G的初始栈大小为2-4K,配置一般的机器也能简简单单开启数十万个Goroutine,而且Go语言在G退出的时候还会把G清理之后放到P本地或者全局的闲置列表gFree中以便复用。

  • M(Machine)
    Go对操作系统线程(OS thread)的封装,可以看作操作系统内核线程,想要在CPU上执行代码必须有线程,通过系统调用clone创建。M在绑定有效的P后,进入一个调度循环,而调度循环的机制大致是从P的本地运行队列以及全局队列中获取G,切换到G的执行栈上并执行G的函数,调用goexit 做清理工作并回到M,如此反复。M并不保留G状态,这是G可以跨M调度的基础。M的数量有限制,默认数量限制是10000,可以通过debug.SetMaxThreads()方法进行设置,如果有M空闲,那么就会回收或者睡眠。

  • P(Processor)
    虚拟处理器,M执行G所需要的资源和上下文,只有将Р和M绑定,才能让P中的G真正运行起来。P的数量决定了系统内最大可并行的G的数量,P的数量受本机的CPU核数影响,可通过环境变量$GOMAXPROCS或在runtime.GOMAXPROCS()来设置,默认为CPU核心数。

  1. CPU感知不到Goroutine,只知道内核线程,所以需要Go调度器将协程调度到内核线程上面去,然后操作系统调度器将内核线程放到CPU上去执行,不会有频繁地的线程切换。
  2. 利用并行(由GOMAXPROCS限制CPU核数)
  3. 有本地队列,协程转移少
  4. Work stealing机制(如果本地队列不存在G,就从其他本地队列中偷取)
  5. Go 1.14中实现了基于信号的"抢占式"调度,当系统时钟中断发生时,运行时会发送一个信号给目标goroutine,强制其主动让出CPU
  6. Hand off机制,不一直阻塞线程
    在这里插入图片描述
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910538.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微服务透传日志traceId

问题 在微服务架构中,一次业务执行完可能需要跨多个服务,这个时候,我们想看到业务完整的日志信息,就要从各个服务中获取,即便是使用了ELK把日志收集到一起,但如果不做处理,也是无法完整把一次业…

【原创】java+ssm+mysql收纳培训网系统设计与实现

个人主页:程序猿小小杨 个人简介:从事开发多年,Java、Php、Python、前端开发均有涉猎 博客内容:Java项目实战、项目演示、技术分享 文末有作者名片,希望和大家一起共同进步,你只管努力,剩下的交…

apache poi 实现下拉框联动校验

apache poi 提供了 DataValidation​ 接口 让我们可以轻松实现 Excel 下拉框数据局校验。但是下拉框联动校验是无法直接通过 DataValidation ​实现,所以我们可以通过其他方式间接实现。 ‍ 步骤如下: 创建一个隐藏 sheet private static void create…

Linux权限概念 | 权限修改

文章目录 1.Linux的权限概念2.Linux权限管理3.文件访问权限的相关设置方法 1.Linux的权限概念 Linux下有两种用户:超级用户(root)和普通用户。对应root用户而言:可以在Linux系统下做任何事情,不受限制。而普通用户&am…

题目练习之二叉树那些事儿(续集)

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ 这一篇博客我们继…

删除MacOS下PowerPoint烦人的加载项

起因 最近要写论文,需要插入很多公式,利用自带的吧,太过繁琐,每次插入都需要点击插入-公式-符号,然后头脑发热想用下本科写论文时用过的MathType,结果这货现在要收费了,新版本只能适用30天&…

清华双臂机器人扩散大模型RDT:先预训练后微调,支持语言、图像、动作多种输入(1B参数)

前言 通过上文介绍的GR2,我们看到了视频生成模型在机器人训练中的应用 无独有偶,和GR2差不多一个时期出来的清华RDT,其模型架构便基于视频生成架构DiT改造而成(当然,该清华团队其实也在DiT之前推出了U-ViT,具体下文会…

Linux下GCC编译器的安装

Linux下GCC编译器的安装 以下所有的版本都可以在https://gcc.gnu.org/pub/gcc/infrastructure/这里找最新的 通过apt-get方式下载的Qt5.9的gcc编译器版本只是4.8.3,无法打开一些Qt5的库头文件,所以准备在Llinux下再安装一个gcc5.3.0。 查看gcc版本 ubu…

qt相关知识

lineEdit中的一些知识 首先我要设置lineEdit中的文本怎么操作 ui->lineEdit->setText(); 如何给窗口设置名字 this->setWindowTitle("计算器"); 如何给按钮设置我们的图片 QIcon ic("图片地址"); ui->button->setIcon(ic…

使用官网tar包制作OpenSSL及OpenSSH rpm包进行升级安装(OpenSSH_9.9p1, without OpenSSL未解决)

一、制作openssl-1.1.1w.rpm包 1、安装基础依赖包和rpmbuild及其依赖包 yum install curl which make gcc perl perl-WWW-Curl rpm-build rpm-build rpmdevtools tree -y yum install gcc-c glibc glibc-devel openssl openssl-devel \pcre-devel zlib zlib-devel perl…

WAL日志

1.WAL概述 PG WAL(Write-Ahead Logging)日志是PostgreSQL数据库中的一种重要机制,用于保证数据库的完整性和数据恢复。 1.1定义与功能 WAL日志是PostgreSQL的持久性技术,它将所有对数据库的修改操作(如INSERT、UPDA…

开放寻址法、链式哈希数据结构详细解读

一、开放寻址法(Open Addressing) 1. 定义 开放寻址法是一种哈希冲突解决策略,所有元素都存储在哈希表中。当发生冲突时,即两个键计算出的哈希值相同时,会按照一定的探查序列查找下一个可用的位置来存储新元素。 2.…

算法通关(4)-- 前缀树

前缀数原理和代码 原理 前缀树(Trie树),也称为字典树,是一种用于高效存储和检索字符串的数据结构。它是一种树形结构,能够利用字符串的公共前缀来减少存储空间和查询时间。 现在有“acb”,"cba","ac…

CSS3新增渐变(线性渐变、径向渐变、重复渐变)

1.线性渐变 代码: 效果图: 使文字填充背景颜色: 效果图: 2.径向渐变 代码: 效果图: 代码图: 效果图: 3.重复渐变 代码: 效果图:

Python 学习完基础语法知识后,如何进一步提高?

入门Python后,就可以拿些小案例练手了,这时候千万不要傻乎乎地成天啃语法书。 编程是一门实践的手艺,讲究孰能生巧。不管是去手撸算法、或者照葫芦画瓢写几个小游戏都可以让你的Python突飞猛进。 之前看github比较多,推荐给大家…

blender导入的图片渲染看不见,图片预览正常,但渲染不出

在使用Blender时,我们经常会遇到导入图片后在预览渲染中显示,但在实际渲染时图片消失的问题。本文将提供详细的解决方法,帮助大家解决“Blender导入的图片渲染图像不显示”的问题。 问题原因 导入的图片在Blender中只是一张图,并…

【数据结构】选择排序——选择排序 和 堆排序

选择排序 和 堆排序 一、选择排序选择排序的思路及其代码选择排序的弊端 二、堆排序三、速度对比同时排10000个数同时排100000个数同时拍500000个数堆排 1 亿个数 一、选择排序 选择排序的思路及其代码 选择排序思路很简单 就是经过将数组遍历选择最小值 将最小值位置的数与数…

Docker在CentOS上的安装与配置

前言 随着云计算和微服务架构的兴起,Docker作为一种轻量级的容器技术,已经成为现代软件开发和运维中的重要工具。本文旨在为初学者提供一份详尽的指南,帮助他们在CentOS系统上安装和配置Docker及相关组件,如Docker Compose和私有…

大数据新视界 -- 大数据大厂之 Impala 性能优化:数据存储分区的艺术与实践(下)(2/30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…