Go线程调度器

基本结构

在这里插入图片描述

字段gcwaiting、stopwait和stopnoted都是串行运行时任务执行前后的辅助协调手段

gcwaiting字段的值用于表示是否需要停止调度

  • 在停止调度前,该值会被设置为1
  • 在恢复调度之前,该值会被设置为0
  • 这样做的作用是,一些调度任务在执行时只要发现gcwaiting的值为1,就会把当前P的状态置为Pgcstop,然后自减stopwait字段的值
  • 如果发现自减后的值为0,就说明所有P的状态都已为Pgcstop
  • 这样就可以利用stopnote字段,唤醒因等待调度停止而暂停的串行时任务了

字段sysmonwait和sysmonnote与前面那一组字段的用户类似,只不过它们针对的是系统监测任务

  • 在串行运行时任务执行之前,系统监测任务也需要暂停
  • sysmonwait字段的作用就是表示是否已暂停,0表示未暂停,1表示已暂停

系统监测任务是持续执行的,更准确地说,它处在无尽的循环之中。在每次迭代之初,系统监测程序都会先检查调度情况

一旦发现调度停止(gcwaiting字段的值不为0或所有的P都已闲置),就会把sysmonwait字段的值设置为1,并利用sysmonnote字段暂停自身。另一方面,在恢复调度之前,调度器发现sysmonwait字段的值不为0,就会把它置为0,并利用sysmonnote字段恢复系统监测任务的执行

一轮调度

在这里插入图片描述

封装main函数的G总是Go运行时创建的第一个用户G。用户G因Go程序中的代码而生,用于封装用户级的程序片段(即需并发执行的函数)。相对的,用户封装运行时任务的G称为运行时G

M锁定的情况

在一轮调度开始处,调度器会先判断当前M是否已被锁定。M和G是可以成对地锁定在一起

锁定M和G的操作可以说是为CGO准备的。CGO代表了Go中的一种机制,是Go程序和C程序之间的一座桥梁。是它们的相互调用成为可能

通过调用runtime.LockOSThread函数,把当前的G与当时运行它的那个M锁定在一起,也可以通过调用runtime.UnlockOSThread函数解除当前G与某个M的锁定

如果调度器在一轮调度之初发现当前M已与某个G锁定,就会立即停止调度并停止当前M(或是说让它暂时阻塞)。一旦与它锁定的G处于可运行状态,它就会被唤醒并继续运行那个G

停止当前M意味着相关的内核线程不能再去做其他事情了。此时,调度器也不会为当前M寻找可运行的G。相应的,当调度器为当前M找到了一个可运行的G,但却发现该G已与某个M锁定,它就会唤醒那个与锁定的M以运行该G,并重新为当前M寻找可运行的G

M未锁定的情况& 串行任务

如果调度器判断当前M未与任何G锁定,那么一轮调度的主流程就会继续进行

调度器会检查是否有运行时串行任务正在等待执行

  • 串行任务,这类任务执行时需要停止Go调度器。官方称此种停止操作为"Stop the world",简称STW

如果gcwaiting字段的值不为0,那么一轮调度流程又会走进另一个分支,即:停止并阻塞当前M以等待运行时串行任务执行完成。一旦串行任务执行完成,该M就会被唤醒,一轮调度也会再此开始

寻找可运行G

如果调度器在此关于锁定和运行时串行任务的判断都为假,就会开始真正的可以运行G寻找之旅。一旦找到一个可运行G,调度器就会判断该G未与任何M锁定之后,立即让当前M运行它

全力查找可运行的G

调度器如果没有找到可运行的G,就会进入“全力查找可运行G”的子流程。这个子流程会多次尝试从各处搜索可运行的G,甚至还会从别的P(非本地P)哪里偷取可运行的G

获取执行终结器的G

一个终结器可以与一个对象关联,通过调用runtime.SetFinalizer函数就可以产生这种关联

当一个对象变为不可达(即:未被任何其他对象引用)时,垃圾回收器在回收该对象之前,就会执行与之关联的终结函数

所有终结函数的执行都会由一个专用的G负责。调度器会在判定这个专用G已完成任务之后试图获取它,然后把它置为Grunnable状态并放入本地P的可运行G队列

从本地P的可运行G队列获取G

调度器会尝试从该处获取一个G,并把它作为结果返回

从调度器的可运行G队列获取G

调度器会尝试从该处获取一个G,并把它作为结果返回

从网络I/O轮询器(或称netpoller)处获取G

如果netpoller已被初始化且已有过网络I/O操作,那么调度器会试着从netpoller哪里获取一个G列表,并把作为表头的那个G当作结果返回,同时把其余的G都放入调度器的可运行G队列

如果netpoller还未被初始化或还未有过网络I/O操作,这一步就会跳过

从其他P的运行G队列获取G

在条件允许的情况下,调度器会使用一种伪随机算法在全局P列表中选取P

然后试着从它们的可运行G队列中盗取(转移)一半的G到本地P的可运行G队列。选取P和盗取G的过程会重复多次,成功即停止

如果成功,那么调度器就会盗取的一个G作为结果返回。否则,搜索的第一阶段就结束了

获取执行GC标记任务的G

在搜索的第二阶段,调度器会先判断是否正处于GC标记阶段,以及本地P是否可用于GC标记任务

如果答案都是true,调度器就会把本地P持有的GC标记专用G置为Grunnable状态并作为结果返回

从调度器的可运行G队列获取G

调度器再次尝试从该处获取一个G,并把它作为结果返回

如果依然找不到可运行的G,就会解除本地P与当前M的关联,并把该P放入调度器的空闲P列表

从全局P列表中每个P的可运行G队获取G

遍历全局P列表中的P,并检查它们的可运行G队列

只要发现某个P的可运行G队列不为空的,就从调度器的空闲P列表中取出一个P,并在判定其可用后与当前M关联在一起,然后再返回第一阶段重新搜索可运行的G

如果所有P的可运行G队列都是空的,那就只能继续后面的搜索

获取执行GC标记任务的G

判断是否正处于GC的标记阶段,以及与GC标记任务相关的全局资源是否可用

如果答案都是true,调度器就会从其空闲P列表拿出一个P。如果这个P持有一个GC标记专用G,就关联该P与当前M,然后再次执行第二阶段

从网络I/O轮询器(netpoller)处获取G

如果netpoller已被初始化了,并且有过网络I/O操作,那么调度器会再次试着从netpoller哪里获取一个G列表

此步骤和之前步骤基本相同,但有一个明显区别:这里的获取是阻塞的

只有当netpoller哪里有可用的G时,阻塞才会解除

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

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

相关文章

阿里云智能编程助手的安装使用

https://help.aliyun.com/document_detail/2590613.html 通义灵码,是阿里云出品的一款基于通义大模型的智能编码辅助工具,提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、代码解释、研发智能问答、异常报错排查等能力&a…

企业互联网建站源码系统 附带完整的安装代码包以及搭建部署教程

系统概述 企业互联网建站源码吸系统是一款集众多先进功能于一身的建站工具。它提供了丰富的模板和组件,允许企业根据自身需求和品牌形象进行个性化定制,快速搭建出具有独特风格的网站。 代码示例 系统特色功能一览 1.用户友好界面:系统采用…

24 年程序员各岗位薪资待遇汇总(最新)

大家好,我是程序员鱼皮。今天分享 24 年 6 月最新的程序员各岗位薪资待遇汇总。 数据是从哪儿来的呢?其实很简单,BOSS 直聘上有一个免费的薪酬查询工具,只要认证成为招聘者就能直接看,便于招聘者了解市场,…

网络安全 文件上传漏洞-20 第二十关 Pass-20

点击进入第二十关,并选择显示代码: $is_upload false; $msg null; if(!empty($_FILES[upload_file])){//检查MIME$allow_type array(image/jpeg,image/png,image/gif);if(!in_array($_FILES[upload_file][type],$allow_type)){$msg "禁止上传该…

Langchain-实战篇-搭建本地问答机器人-01

项目背景 在这个快节奏的职场世界里,我们每个人都可能在某个时刻,化身为一头辛勤的牛或一匹奔腾的马,面对入职签合同时的迷茫,或是离职时的纠纷,心中难免会涌现出各种疑问。比如: "这份合同里的条款…

Mongodb集群中的分布式读写

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第81篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…

百元蓝牙耳机推荐2024,百元蓝牙耳机排行榜盘点

在2024年面对琳琅满目的蓝牙耳机选项,消费者往往难以抉择,特别是在预算有限的情况下,如何在众多产品中挑选出既满足质量又符合预算的耳机成为了一个不小的挑战。 为了帮助大家在繁多的选择中找到真正物有所值的百元蓝牙耳机,我们…

vue响应式原理细节分享

在讲解之前,我们先了解一下数据响应式是什么?所谓数据响应式就是建立响应式数据与依赖(调用了响应式数据的操作)之间的关系,当响应式数据发生变化时,可以通知那些使用了这些响应式数据的依赖操作进行相关更…

【JavaEE】JVM

文章目录 一、JVM 简介二、JVM 运行流程三、JVM 运行时数据区1、堆(线程共享)2、Java虚拟机栈(线程私有)3、本地方法栈(线程私有)4、程序计数器(线程私有)5、方法区(线程…

# 音频处理4_傅里叶变换

1.离散傅里叶变换 对于离散时域信号 x[n]使用离散傅里叶变换(Discrete Fourier Transform, DFT)进行频域分析。 DFT 将离散信号 x[n] 变换为其频谱表示 X[k],定义如下: X [ k ] ∑ n 0 N − 1 x [ n ] e − j 2 π k n N X[k]…

.NET 漏洞情报 | 某整合管理平台SQL注入

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

揭秘Wish自养号秘诀:新手卖家如何快速出单?

对于卖家来说,如果想要提升店铺的转化率和销量,有几个关键策略是必不可少的: 一、精心挑选热销产品 成功的第一步在于选品。选择热销产品如同掌握了成功的钥匙。卖家需要深入分析平台用户群体,了解他们的需求和偏好。例如&#…

Tampermonkey 油猴脚本使用教程

Tampermonkey 油猴脚本使用教程 一、Tampermonkey 油猴脚本简介 Tampermonkey 是一款流行的浏览器扩展,它允许用户通过用户脚本增强网页功能或改变网页的外观。它支持包括 Chrome、Microsoft Edge、Safari、Opera Next 和 Firefox 在内的多种浏览器。Tampermonkey…

【C++ 初阶路】--- C++内存管理

目录 一、C/C内存分布二、C内存管理方式2.1 new/delete操作内置类型2.2 new和delete操作自定义类型 三、operator new与operator delete函数四、new和delete的实现原理4.1 内置类型4.2 自定义类型 一、C/C内存分布 int globalVar 1; static int staticGlobalVar 1; void Tes…

大模型+多模态合规分析平台,筑牢金融服务安全屏障

随着金融市场的快速发展,金融产品和服务日趋多样化,消费者面临的风险也逐渐增加。 为保护消费者权益,促进金融市场长期健康稳定发展,国家监管机构不断加强金融监管,出台了一系列法律法规和政策文件。对于金融从业机构…

代码托管服务:GitHub、GitLab、Gitee

目录 引言GitHub:全球最大的代码托管平台概述功能特点适用场景 GitLab:一体化的开发平台概述功能特点适用场景 Gitee(码云):中国本土化的代码托管服务概述功能特点适用场景 功能对比结论 引言 在现代软件开发中&#…

Pickle, SafeTensor, GGML和GGUF

如今,大型语言模型的使用方式有以下几种: 作为 OpenAI、Anthropic 或主要云提供商托管的专有模型的 API 端点作为从 HuggingFace 的模型中心下载的模型工件和/或使用 HuggingFace 库进行训练/微调并托管在本地存储中作为针对本地推理优化的格式的模型工…

机器学习 中数据是如何处理的?

数据处理是将数据从给定形式转换为更可用和更理想的形式的任务,即使其更有意义、信息更丰富。使用机器学习算法、数学建模和统计知识,整个过程可以自动化。这个完整过程的输出可以是任何所需的形式,如图形、视频、图表、表格、图像等等&#…

Linux基础篇——目录结构

基本介绍 Linux的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录"/",然后在根目录下再创建其他的目录 在Linux中,有一句经典的话:在Linux世界里,一切皆文件 Linux中根目录下的目录 具体的…

PHP留守儿童关爱之家网站-计算机毕业设计源码11079

目录 1 绪论 1.1 研究背景 1.2研究意义 1.3 论文结构与章节安排 2 留守儿童关爱之家网站系统分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程和逻辑 2.5本章小结 3 留守儿童关爱之家网站总体设计 3.1系统结构设计 3.2系统功能模块设计 3.2 数…