当前位置: 首页 > news >正文

【golang】调度系列之P

调度系列
调度系列之goroutine
调度系列之m

在前面两篇中,分别介绍了G和M,当然介绍的不够全面(在写后面的文章时我也在不断地完善前面的文章,后面可能也会有更加汇总的文章来统筹介绍GMP)。但是,抛开技术细节,我想经过前面两篇,应该已经对GMP建立了基本的认知。GMP本质就是个任务处理系统,G是任务,M是worker,runtime创建一定数量的worker来运行任务。

一个简单的任务处理系统,只任务和worker两个对象足够胜任。从这个角度来说,似乎GM就足够了,并不需要P。实际上,golang的调度系统最开始就是采用了GM模型。然而golang的调度系统显然不是简单的任务处理系统,而是一个复杂度非常高的任务系统,在迭代过程中遇到了很多的问题。为了解决这些问题,runtime在G和M之间引入了一个中间层,就是P。任何计算机科学领域的问题都可以通过引入一个中间层来解决,越来越觉得这句话是大道至简、大音希声。

关于runtime调度系统演进过程的细节可以参见google的文档google doc,这里就不过多介绍。

文章目录

  • 状态图
  • P的结构

状态图

在介绍具体的细节前,先介绍下P整体的状态的流转。P的状态相对G的状态要简单一些,相对M的状态则要复杂得多。P的状态和G一样,具有明确定义的可枚举的状态值。

  • idle。P处于空闲状态。此时的P没有被用来运行用户的goroutine或者时runtime的代码,也可以说P并没有被具体的m持有。大多数情况下,处于idle状态的P应该位于全局的idle list中。
    为什么这里说大多数呢?这和runtime的实现相关。在runtime的实现中,由其他状态(syscall、gcstop)转变为running时,会先转变为idle,再由idle转变为running。
  • running。P处于运行状态。此时P被m持有,被用来运行用户的goroutine或者runtime的代码。对应的m可能处于running、spinning状态。running状态应该是最好理解的状态,P大部分时间也应该处于running状态。
  • syscall。P处于系统调用状态。当P上运行的g进入系统调用时m会与P解绑,将P置为syscall状态。当系统调用结束时,m会首先尝试获取原来的P,再尝试获取idle list中的P,如果拿不到则挂起。
    P进入syscall时根据系统调用时间长短有两种选择,当系统调用时间较短时P处于syscall等待m;当系统调用时间比较长时,会调用handoffp将p转移给其他的m继续执行g。
    以上的操作都是在runtime中通过pre hook和post hook的方式实现的。
  • gcstop。P处于STW状态。P由running转变为gcstop时会和当前的m解绑,当strat the word时,会重新驱动m来获取P。
  • dead。P处于死亡状态。只有调用procresize方法缩减P的数量时才会触发,调用p.destroy方法,释放所有的资源。当procresize只有在stop the world时才会调用,所以dead只能由gcstop转变而来(不是很确定)。

状态流转图如下。

简单介绍P的状态流转。

  • runtime初始化时会调用procresize创建GOMAXPROCS个P,初始化时P的状态会在p.init中被设为gcstop,但最终会被设为idle,并加入全局的idle list中。
  • 当有goroutine创建(newproc)或者goroutine就绪(goready)时,会调用wakep。如果存在idle的p并且没有自旋的m,wakep启动m将idle的P转变为running。
  • running状态的P可以转变为gcstop、idle、syscall。
    • 当m在运行findrunnable时发现runtime需要gc(gcwaiting!=0),会将P转变为gcstop状态并和P进行解绑;
    • 当m在findrunnable中找不到可运行的任务时,会将P转变为idle状态并挂起;
    • 当m(g)调用系统调用时,会将P转变为syscall状态;
    • 另外在一些情况下,m也会调用handoffp主动转移P的持有,比如runtime判断一个系统调用的时间比较长是,会将P转变为syscall,然后主动handoffp转移P的持有;

P的结构

P的字段很多,这里同样就挑几个重要的说明。可见下图。

  • 资源相关。
    引入P的一个最大的好处就是减少了资源的浪费。在GM相关的模型中,运行goroutine相关的资源是分配给每个M的,比如内存。但是在生产系统中,真正运行的m的数量占总数的比例很小,大多数可能在阻塞中。这样就导致了资源的浪费。引入P后,相关的资源都分配给P,m在执行时首先要获取P。这样就大大减少了资源的浪费。所以P中有很多资源相关的字段,比如mcache、pcache、mspan等。
    另外,比如向timer类似的数据结构,也从全局对象变为每个P持有的对象。这样做可以大大减少并发冲突。因为同一个P上同时最多只有一个goroutine执行,并发只存在跨P的操作中。
  • 调度相关。
    之前在goroutine和M的介绍中提到了很多调度相关的内容。但其中的内容都是属于主动调度。runtime中真正的异步抢占或者说异步调度是依靠sysmon来实现的。sysmon是一个独立的m,并且其运行不需要持有P。sysmon会定期的扫描每个P,如果goroutine占据P的时间超过10ms,怎会触发异步抢占。其中schedtick、syscalltick、sysmontick等字段都是和sysmon相关。关于sysmon,我们会在后面再详细介绍。

至此,对G、M、P都有了单独的介绍和认识,对runtime的调度系统,应该有了初步和大概的认识。注意,runtime中还有一个全局的schedt对象,但是该对象仅保存一些全局的数据,而不负责具体的调度,所以不单独介绍。后面我们会结合前面G、M、P的介绍,对调度整体进行介绍,并陆续地针对细节进行补充。

相关文章:

【golang】调度系列之P

调度系列 调度系列之goroutine 调度系列之m 在前面两篇中,分别介绍了G和M,当然介绍的不够全面(在写后面的文章时我也在不断地完善前面的文章,后面可能也会有更加汇总的文章来统筹介绍GMP)。但是,抛开技术细…...

Vue3中watch用法

在 Vue3 中的组合式 API 中,watch 的作用和 Vue2 中的 watch 作用是一样的,他们都是用来监听响应式状态发生变化的,当响应式状态发生变化时,都会触发一个回调函数。 当需要在数据变化时执行异步或开销较大的操作时,com…...

组里来了一个实习生,一行代码引发了一个惨案

大家好,我是静幽水,一名大厂全栈程序员,今天给大家分享一个案例,看似简单。却容易引发惨案。 事情是这样的,最近组里来了一个实习生,因为项目工作量大,人力比较紧张,所以就分配了一…...

随手笔记(四十五)——idea git冲突

图片为引用,在一次导入项目至gitee的过程中,不知道为什么报了403,很奇怪的一个错误,网上很多的答案大概分成两种。 第一种是最多的,直接找到windows凭据删掉 很抱歉的告诉各位,你们很多人到这里就已经解…...

chacha20 算法流程

chacha20算法请参看 RFC:7539。下面是我的理解,欢迎指正。 chacha20算法的基本思想:加密时,将明文数据与用户之间约定的某些数据进行异或操作,得到密文数据;由异或操作的特点可知,在解密时,只需…...

准备篇(三)Python 爬虫第三方库

第三方库无法将 "pip" 识别ModuleNotFoundError: No module named pip install 安装路径相关问题requests 库和 BeautifulSoup 库requests 库BeautifulSoup 库第三方库 Python 的 标准库 中提供了许多有用的模块和功能,如字符串处理、网络通信、多线程等,但它们并…...

从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动

从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动 文章目录 从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动一、前言1、大纲 二、VR射线移动功能实现与解析1、区域传送(1)新建 XR Orig…...

防止攥改之水印功能组件

防止攥改之水印功能组件 效果图逻辑代码 效果图 逻辑代码 <template><div class"containerBox" ref"parentRef" style"height: 300px;background-color: red;"><slot></slot></div> </template><script…...

iOS 17 适配 Xcode 15 问题

在适配 iOS 17 xcode 15时遇到的问题&#xff0c;记录一下。 1、 Could not build module ‘WebKit’ type argument nw_proxy_config_t (aka struct nw_proxy_config *) is neither an Objective-C object nor a block type解决方案&#xff1a; 选中不能编译的库的xcodep…...

Element Plus 快速开始

1.完整引入&#xff08;全局引入&#xff09; // main.ts import { createApp } from vue import ElementPlus from element-plus import element-plus/dist/index.css import App from ./App.vueconst app createApp(App)app.use(ElementPlus) app.mount(#app) npm install e…...

华为云云耀云服务器L实例评测|StackEdit中文版在线Markdown笔记工具

华为云云耀云服务器L实例评测&#xff5c;StackEdit中文版在线Markdown笔记工具 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 应用场景1.3 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 StackEdit 中文版3.1 StackEdit 介绍3.2 环…...

MyEclipse报错javax/persistence/EntityManagerFactory

MyEclipse报错&#xff1a; Build path is incomplete. Cannot find class file for javax/persistence/EntityManagerFactory 解决方案&#xff1a; 引入依赖 <dependency><groupId>javax.persistence</groupId> <artifactId>persistence-api</a…...

【MySQL进阶】SQL性能分析

一、SQL性能分析 1.SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供服务器状态信 息。通过如下指令&#xff0c;可以查看当前数据库的 INSERT 、 UPDATE 、 DELETE 、 SELECT 的访问频次&#xff1a; -- session 是查看当…...

在SpringBoot项目中整合SpringSession,基于Redis实现对Session的管理和事件监听

1、SpringSession简介 SpringSession是基于Spring框架的Session管理解决方案。它基于标准的Servlet容器API&#xff0c;提供了Session的分布式管理解决方案&#xff0c;支持把Session存储在多种场景下&#xff0c;比如内存、MongoDB、Redis等&#xff0c;并且能够快速集成到Spr…...

浅析vue中computed,method,watch,watchEffect的区别

方法methods只要调用每次都会执行watch(惰性)只有依赖项更新才会执行回调函数&#xff0c;且组件初次渲染不会执行watchEffect:自动追踪依赖变化&#xff0c;只要依赖更新即执行回调函数&#xff0c;且组件初次渲染即执行回调函数computed(惰性): 返回一个只读的ref,具有缓存功…...

activiti7的数据表和字段的解释

activiti7的数据表和字段的解释 activiti7版本有25张表&#xff0c;而activiti6有28张表&#xff0c;activiti5有27张表&#xff0c;绝大部分的表和字段的含义都是一样的&#xff0c;所以本次整理的activiti7数据表和字段的解释&#xff0c;也同样适用于activiti6和5。 1、总览…...

Java手写Trie树和Trie树应用拓展案例

Java手写Trie树和Trie树应用拓展案例 1. 算法思维导图 以下是使用mermaid代码表示的Trie树的实现原理&#xff1a; #mermaid-svg-5twy24X7Wqbhyulb {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5twy24X7Wqbhyul…...

alova.js快速入门教程

官网地址&#xff1a;Alova.JS - Lightweight request strategy library | Alova.JS 目录 一、alova 是什么&#xff1f; 二、 快速入门 1、安装依赖 &#xff08;1&#xff09;使用npm方式安装 &#xff08;2&#xff09;使用yarn方式安装 2、在静态 html 中使用 一、al…...

获取IP地址-根据IP获取位置信息

获取外网IP地址&#xff0c;并得到该地址所在位置&#xff1b; 如&#xff1a;101.249.255.255 对应&#xff1a;西藏自治区-拉萨市-堆龙德庆区 string ipAddress GetIPAddress(); string location GetIPLocation(ipAddress); /// <summary>/// 获取IP地址/// </s…...

Android13适配-Google官方照片视频选择器

官方照片选择器 图 1. 照片选择器提供了一个直观的界面&#xff0c;便于与您的应用分享照片。 照片选择器的界面可供浏览和搜索&#xff0c;并按日期降序向用户显示其媒体库中的文件。如隐私保护最佳实践 Codelab 中所示&#xff0c;照片选择器为用户提供了一种安全的内置授权…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...