当前位置: 首页 > 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;照片选择器为用户提供了一种安全的内置授权…...

云计算的发展趋势和挑战

本文将探讨云计算的发展趋势和挑战&#xff0c;旨在帮助读者了解云计算的最新动态和未来发展方向。 随着信息技术的发展&#xff0c;云计算作为一种新兴的计算模式&#xff0c;已经得到了广泛的应用和认可。它通过将计算资源、存储资源和应用程序等服务通过互联网提供给用户&a…...

PyG-GAT-Cora(在Cora数据集上应用GAT做节点分类)

文章目录 model.pymain.py参数设置运行图 model.py import torch.nn as nn from torch_geometric.nn import GATConv import torch.nn.functional as F class gat_cls(nn.Module):def __init__(self,in_dim,hid_dim,out_dim,dropout_size0.5):super(gat_cls,self).__init__()s…...

java专项练习(验证码)

package 专题练习;import java.util.Random;public class Developing_CAPTCHA {public static void main(String[] args) {/* 需求:定义方法生成一个5位的验证码 验证码长度为5,前四位为大或小写字母,最后一位是数字*///方法: 如果我们要在一堆没有规律的数据中随机抽取,可以先…...

MS1861 视频处理与显示控制器 HDMI转MIPI LVDS转MIPI带旋转功能 图像带缩放,旋转,锐化

1. 基本介绍 MS1861 单颗芯片集成了 HDMI 、 LVDS 和数字视频信号输入&#xff1b;输出端可以驱动 MIPI(DSI-2) 、 LVDS 、 Mini-LVDS 以及 TTL 类型 TFT-LCD 液晶显示。可支持对输入视频信号进行滤波&#xff0c;图 像增强&#xff0c;锐化&#xff0c;对比度调节&am…...

广州华锐互动:利用VR复原文化遗址,沉浸式体验历史文物古迹的魅力

在过去的几十年里&#xff0c;科技发展飞速&#xff0c;为我们打开了无数新的视角和可能性。其中&#xff0c;虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术的崭新应用&#xff0c;为我们提供了一种全新的、近乎身临其境的体验历史的方式。本文将重点…...

微信小程序——事件监听

微信小程序是一种轻量级的应用程序&#xff0c;它在移动设备上提供了丰富的用户体验。在开发微信小程序时&#xff0c;事件监听是一项重要的技术&#xff0c;它允许开发者捕捉和处理用户的各种操作。本文将介绍微信小程序事件监听的概念、用法和一些实用示例。 1. 什么是事件监…...

View绘制流程的源码所得

一些问题 子线程可以更新 UI 吗 答案是可以的&#xff0c;在特定的情况下可以 可以先在主线程中调用requestLayout() 方法&#xff0c;然后紧接着在子线程中更新UI&#xff08;原理&#xff1a;不要在子线程触发 checkThread() 方法&#xff0c;而checkThread() 方法的调用时…...

企业级数据仓库-理论知识

D3 AM 大数据中间件 Hive&#xff1a;将SQL转化成分布式Map/Reduce进行运算&#xff0c;也支持转换成Spark,需要单独安装Hive集群才能访问Spark,支持60%的SQL&#xff0c;延迟比较大。SparkSQL:属于Spark生态圈&#xff0c;Hive on Sqark。HBase: NoSQL,高并发读&#xff0c;适…...

解决flutter不识别yaml里面配置的git项目

解决办法找到相应的 git路径&#xff0c;然后手动 git pull 暂时先用这个笨方法&#xff0c;后面有更好的解决办法了再说 studio 自己拉取的项目里面没有ios 和lib包...

rust结构体

一、定义结构体类型 语法 struct Name_of_structure {field1: data_type,field2: data_type,field3: data_type, }注意&#xff1a; 不同于C&#xff0c;Rust的struct语句仅用来定义类型&#xff0c;不能定义实例。 结尾不需要;。 每个字段定义之后用 , 分隔。最后一个逗号可…...

工程信息网站谁做/百度新闻客户端

Introduction 参考链接&#xff1a;2014斯坦福大学机器学习视频 本篇是针对当凭直觉做完一个Baseline以后&#xff0c;如何提高现有的识别率?依然凭直觉有以下几种方法&#xff1a; 1、增加训练数据集 2、挑选出更少的特征 3、增加其他特征 4、增加多项式x1*x2 5、减少…...

wordpress app应用/上海网站排名优化

没有学习过红黑树的同学请参考&#xff1a; <<Introduction to Algorithms>> Chapter 13 Red-Black Trees Chapter 14 Augmenting Data Structures 教你透彻了解红黑树 一、红黑树的介绍 先来看下算法导论对R-B Tree的介绍&#xff1a;红黑树&#xff0c;一种二叉…...

椒江做国际网站的公司/数据营销

在一个仓库里&#xff0c;有一排条形码&#xff0c;其中第 i 个条形码为 barcodes[i]。 请你重新排列这些条形码&#xff0c;使其中两个相邻的条形码 不能 相等。 你可以返回任何满足该要求的答案&#xff0c;此题保证存在答案。 示例 1&#xff1a; 输入&#xff1a;[1,1,1,…...

网站建设广东/南京seo网站优化

cpuid.1.eax "0000:0000:0000:0001:0000:0110:1010:0101"转载于:https://www.cnblogs.com/mrhgw/archive/2012/07/11/2586942.html...

世界杯网站建设/网络推广主要工作内容

指针运算 例1 #include <stdio.h>int main (void) {int a 0;int *p &a;printf("%p, %p, %p",p,p1,p2);return 0;}输出结果&#xff1a; **指针变量可以计算&#xff0c;如果int 类型加一&#xff0c;变化4个整数&#xff0c;如果char 加一&#xff0c…...

wordpress 数据库类型/网络优化大师app

Eclipse 4Diac 网站上有介绍将&#xff14;diac的Forte 移植到freeRTOS 的简单介绍&#xff0c; https://www.eclipse.org/4diac/en_help.php?helppagehtml/installation/freeRTOSLwIP.html 但是网络上并没有如何将forte 移植到STM32F上的详细说明。我成功地将4diac 移植到…...