Go调度器什么时候会创建新的M和P?

2023-12-04

刚刚学习了golang GMP模型,现在我了解了goroutines、操作系统线程和golang上下文/处理器如何相互协作。但我还是不明白什么时候会产生M和P?

例如,我有一个测试代码来在数据库上运行一些操作,并且有两个测试用例(两批 goroutine):

func Test_GMP(t *testing.T) {
    for _ = range []struct {
        name string
    }{
        {"first batch"},
        {"second batch"},
    } {
        goroutineSize := 50
        done := make(chan error, goroutineSize)
        for i := 0; i < goroutineSize; i++ {
            go func() {
                // do some databases operations...
                // each goroutine should be blocked here for some time...

                // propogate the result
                done <- nil
            }()
        }

        for i := 0; i < goroutineSize; i++ {
            select {
            case err := <-done:
                assert.NoError(t, err)
            case <-time.After(10 * time.Second):
                t.Fatal("timeout waiting for txFunc goroutine")
            }
        }
        close(done)
    }
}

以我的理解,如果M是在需要时创建的。在第一批 goroutine 中,将创建 8 个(我计算机上的虚拟核心数量)操作系统线程,第二批将仅重用这 8 个操作系统线程,而不创建新线程。那是对的吗?

如果您可以提供有关此主题的更多材料或博客,我们将不胜感激。


仅当您的进程没有阻塞或没有任何系统调用时,M 才可重用。在你的情况下,你的内部有阻塞任务go func()。因此,M 的数量不会限制为 8(我计算机上的虚拟核心数)。第一批将阻塞并从 P 中删除,并等待阻塞进程完成,同时新的 M 创建与 P 的关联。

  1. 我们通过Go func()创建一个goroutine;

  2. 存储G的队列有两个,一个是本地调度器P的本地队列,一个是全局G队列。新创建的G将是 保存在P的本地队列中,如果P的本地队列为 full,将保存在全局队列中;

  3. G只能在m中运行,一个m必须持有一个P,M和P是1:1 关系。 M会从P的本地队列中弹出一个可执行文件G。 如果本地队列为空,你会认为其他MP组合 窃取可执行文件 G 来执行;

  4. M调度G执行的一个进程是循环机制;

  5. 当M执行syscall或者剩下的阻塞操作时,M会阻塞,如果有一些g在执行,Runtime会移除这个 来自 P 的线程 M,然后创建一个新的操作系统线程(如果 有一个空闲线程可用于复用空闲线程)来服务 这个P;

  6. 当M系统调用结束时,该G将尝试获取一个空闲的P执行并将其放入该P的本地队列中。如果你得到P,那么这个 线程m变为睡眠状态,将其添加到空闲线程中,然后 这个G将会被放入全局队列中。

1、P数量:

环境变量$GomaxProcs是由Runtime决定的 方法gomaxprocs()时环境变量被调度。后 GO1.5、GomaxProcs 将默认设置为可用内核,并且 在默认之前它是 1。这意味着只有 $GOMAXPROCS Goroutine 是 任何时候同时运行执行。

2、M数量:

GO语言本身限制:当GO程序启动时,最大 number of M 将设置最大M数。然而,内核是 很难支持这么多线程,所以这个限制可以忽略。 SetMaxThreads函数在运行时/调试时,设置最大线程数M 一个M阻塞,你就会创建新的M。

M和P的数量没有绝对关系,一个m块,p 会创建或切换另一个M,所以即使P的默认数量是 1、可能有很多M出来。

请参阅以下内容了解更多详情,

  • https://www.programmerought.com/article/795578​​85527/
  • go-goroutine-os-thread-and-cpu-管理
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go调度器什么时候会创建新的M和P? 的相关文章

  • 发布/订阅架构

    我尝试编写一个发布 订阅系统 客户端和服务器端 其中客户端接收定期更新 如心跳 消息控制 并可以向服务器发出命令 订阅某些源 这样做的好方法是什么 我已经有一个实现线程池的服务器来管理传入的客户端连接 我想知道如何处理连接双方都可以在 Ne
  • (nasm x86实模式)如何在引导加载的扇区中写入/读取字符串?

    我正在使用 NASM 为 x86 实模式编写一个最小操作系统 用于教育目的 我想使用 512 字节引导扇区加载包含操作系统其余部分的更大扇区 我已经成功创建了一个加载另一个扇区的引导扇区 但我似乎无法在加载的扇区中写入 读取字符串 这是我的
  • Shared_ptr 线程安全的开销是多少?

    std shared ptr保证是线程安全的 我不知道典型的实现使用什么机制来确保这一点 但肯定它必须有一些开销 即使您的应用程序是单线程的 这种开销也会存在 是上述情况吗 如果是这样 如果您不使用线程安全保证 这是否意味着它违反了 您不为
  • 退出代码大于 255 — 可能吗?

    如果是 在哪个操作系统 shell 或其他操作系统上 考虑以下 Java 程序 我使用 Java 只是作为示例 任何语言都适合这个问题 这更多地与操作系统有关 public class ExitCode public static void
  • 原始类型是易失性的还是同步的?

    在 Java 中 如果变量的大小小于或等于 32 位 则赋值是原子的 但如果变量的大小大于 32 位 则赋值不是原子的 在双重或长分配的情况下 使用什么 易失性 同步 会更有效 Like volatile double x y 同步不适用于
  • 有哪些学习线程编程的好资源? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 随着多核CPU在桌面上的兴起 多线程技能将成为程序员的宝贵资产 您能为想要学习线程编程的程序员推荐一些好的资源 书籍 教程 网站等 吗 看
  • ThreadPoolExecutor 和队列

    我以为使用线程池执行器 http docs oracle com javase 6 docs api java util concurrent ThreadPoolExecutor html我们可以提交Runnables 要在以下位置执行B
  • 为什么绿色线程不能在多核上工作

    在维基百科上 绿色线程 http en wikipedia org wiki Green threads被描述为通常无法在多核上运行 而没有解释原因 在多核处理器上 本机线程实现可以 自动将工作分配给多个处理器 而绿色线程 实现通常不能 我
  • 使用 OpenTelemetry 统一不同服务的范围

    我刚刚开始使用 OpenTelemetry 并为此创建了两个 微 服务 Standard and GeoMap 最终用户将请求发送到Standard服务 该服务又将请求发送到GeoMap在将结果返回给最终用户之前获取信息 我使用 gRPC
  • 如何在给定点停止线程?

    我试图停止一些线程 阅读一些有关优雅地执行此操作的正确方法的内容 但我一定做错了什么 因为它根本不起作用 起初我尝试不使用lock with IsRunning不稳定 然后尝试使用锁 这是我所拥有的 private volatile boo
  • 当可能存在迭代器时替换并发集合是否是线程安全的?

    我一直在阅读各种内容 似乎这应该有效 但我想确定一下 我有一个静态属性 它应该是一个缓存 加上一些与缓存数据相关的其他功能 它将实际数据存储在 ConcurrentBag 中 并且有一个 IEnumerable 方法来 过滤并 从此包中生成
  • 为什么 Go 中只有 int 而没有 float?

    在 Go 中 有这样的类型int这可能相当于int32 or int64取决于系统架构 我可以声明一个整数变量而不用担心它的大小 var x int 为什么没有这个类型float 这相当于float32 or float64取决于我的系统架
  • iPhone 应用程序中的异步、同步、线程

    我正处于一个应用程序的设计阶段 该应用程序将利用 REST Web 服务 并且在使用异步 同步和线程方面遇到了困境 这是场景 假设您有三个选项可供深入研究 每个选项都有自己的基于 REST 的资源 我可以使用同步请求延迟加载每个请求 但这会
  • 使用覆盖率信息测试 Go 中的 os.Exit 场景 (coveralls.io/Goveralls)

    这个问题 如何在 Go 中测试 os exit 场景 https stackoverflow com questions 26225513 how to test os exit scenarios in go 以及其中得票最高的答案 列出
  • 我们可以使用 x86_64 CPU 原子在 PCI Express 上生成复合原子操作吗?

    如您所知 从2 0版本开始 PCI Express支持复合原子操作 FetchAdd Swap CAS https pcisig com sites default files specification documents ECN Ato
  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • asp.net core / kestrel中的线程管理

    我正在解决我们已迁移到 asp net core 2 0 的 asp net 应用程序的性能 可扩展性问题 我们的应用程序作为应用程序服务托管在 azure 上 并且在任何中等流量的情况下都很容易崩溃 让我困惑的一件事是如何处理多个并发请求
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现

随机推荐

  • 是否可以编辑 UIAlertAction 标题字体大小和样式?

    现在iOS8已经弃用了UIActionsheet and UIAlertviewiOS7 上的自定义不再生效 到目前为止 我知道的唯一定制是色调颜色 我需要的是改变标题的字体大小和样式 但我还没有找到任何方法可以用新的UIAlertActi
  • SQL AND 运算符无法正常工作

    我有以下两张表 地块表 Blockid ParcelNo storPri 52000105 3 State 52000105 4 Private 52000105 5 State 行动表 Blockid ParcelNo ActionTak
  • Pandas 中的可变位移

    数据框中有两列 A 和 B A B 0 1 6 1 2 7 2 1 8 3 2 9 4 1 10 我想创建一个列 C C 必须将 B 的值移动 A 的值 A B C 0 1 6 NaN 1 2 7 NaN 2 1 8 7 3 2 9 7 4
  • ImageMagick 比较:忽略 PSNR 结果中的白色匹配

    我在用着compare区分两个相似的colorPNG 文件 他们得到一个PSNR值 27 图像包含许多白色区域 两个图像之间始终匹配 如果我错了 请纠正我 但这些白色区域正在增加 PSNR 值 使图像作为平均值更加相似 因此我不想考虑白色像
  • 如何以编程方式在所需文件夹中创建 SQL Server 2008 数据库完整备份

    如何使用 Microsoft Visual Studio 2010 c 以编程方式在所需文件夹中创建 SQL Server 2008 数据库完整备份 只需执行 SQL Servercommand BACKUP DATABASE databa
  • C11 中的内存顺序消耗使用情况

    我读到了关于带有依赖性关系和依赖顺序先于在其定义中使用 15 1 2 4 p16 评价A在评估之前是依存顺序的B if A对原子对象执行释放操作M 并且 在另一个 线 B执行消费操作M并读取写入的值 由释放序列中的任何副作用引起A or 一
  • Apache Lucene 大型 XML 文件索引

    我是 lucene 新手 我想用 lucene 索引包含纯文本 属性和许多 xml 标签的大型 xml 文件 15GB 如何使用 lucene 和任何示例解析此 xml 文件并为其建立索引 如果我们使用 lucene 我们需要任何数据库 如
  • Inno Setup:调整卸载进度表及其所有组件的大小

    嘿 我需要增加宽度和高度UninstallProgressForm我的 Inno Setup 卸载程序 当我根据我的自定义设计的安装程序向导页面宽度和高度手动更改其宽度和高度时 卸载进度表显得很奇怪 唯一改变的是它的宽度和高度 所有其他组件
  • 使用 Attach 时 R 中的命名冲突

    我感觉好像在 R 中经常出现奇怪的命名冲突 附加数据帧和其他对象之间 附加 分离不能按预期工作 只是附加了同一数据帧的两个副本 甚至不确定它们是否相同 和整个软类型语言特定问题 一小时前工作的代码突然产生新的错误等 是否有处理此类事情的最佳
  • 如何在pygame中让相机跟随自上而下的汽车

    一般来说 对 pygame 和游戏编程不熟悉 只是想知道如何让相机在自上而下的汽车游戏中跟随汽车 没什么花哨的 想想微型机器 我正在使用 Python 3 6 并且有一辆可以旋转和移动的自行车 我在这里保留了更短的代码 但如果相机正常工作
  • 如何创建一个新的 Moose 类并在运行时实例化该类的对象?

    使用创建元类后Moose Meta Class gt create 我如何实例化一个真正的 Moose 类 并将该类作为元类 我还需要创建元类 因为我还想对其应用一些角色 当然 元类就是类 如果您想要该类的实例 只需执行以下操作 my in
  • 仅在 320x480 区域检测到 iPad 触摸

    我正在升级 iPhone 应用程序 到目前为止一切进展顺利 设法调整大多数表单的屏幕显示大小 但是 我无法解决一个问题 仅在旧的 320x480 区域中检测到触摸 我有什么想法可以解决这个问题吗 Thanks 编辑 以下是执行获取超级视图边
  • 本地化 ASP.NET MVC 应用程序母版页中的字符串

    I have 设法本地化视图页面在我的应用程序中 但有包含一些字符串的母版页 看来母版页中包含的字符串必须添加到每个页面的资源文件中 这看起来很可怕 如何优雅地本地化母版页中的字符串 如果您不想弄乱访问修饰符 您可以创建一个助手来简化访问资
  • Ormlite - 扩展 BaseDaoImpl 时构造函数调用失败

    我有以下表格 DatabaseTable tableName b daoClass B DaoImpl class public class B DatabaseField public String b1 public B For Orm
  • 如何在 SQL 动态查询中使用 Pass 逗号分隔字符串

    我有一个函数将从逗号分隔的字符串返回整数值 它需要两个参数 string nvarchar 4000 delimiter char 1 所以问题是 如果我在动态查询中使用这个函数 我会收到错误 这里是查询 declare ProductID
  • 无法将 JMX 与 Spring 应用程序集成

    我有一个SPRING应用 当我跑步时 mvn jetty run 一切都好 我想用JMX在我的项目中 我创建了另一个项目 我尝试了初学者教程 我能够看到一些变化jconsole 现在 我想在我的实际项目中使用 JMX 并且我想使用管理 JM
  • 如何将 Django 应用程序测试拆分到多个文件中

    我正在开发 Django 1 2 应用程序 并且我是该框架的初学者 我想将我的测试拆分为应用程序的多个文件https github com vkhemlan BolsaTrabajo tree master bolsa trabajo 我怎
  • 在 Cassandra 中创建触发器的示例,仅支持 Java 吗?

    想要检查 Cassandra 中的触发器功能 有人可以提供一个创建触发器的示例吗 从这个博客 http www datastax com dev blog whats new in cassandra 2 0 prototype trigg
  • “为什么”Python 数据类型是不可变的

    Why 不是如何 像 int 和 string 这样的 python 原始数据类型是不可变的 这是因为脚本语言的实现限制吗 举个例子 a 5 a 6 在第二行 a 6 而不是创建一个新的内存位置 为什么不能将第一个内存位置更改为6 某些 P
  • Go调度器什么时候会创建新的M和P?

    刚刚学习了golang GMP模型 现在我了解了goroutines 操作系统线程和golang上下文 处理器如何相互协作 但我还是不明白什么时候会产生M和P 例如 我有一个测试代码来在数据库上运行一些操作 并且有两个测试用例 两批 gor