<td id="hmpli"></td>
  • <td id="hmpli"></td>

    侵权投诉

    详解剖析Go语言调度模型的设计

    马哥Linux运维 ? 2021-07-26 10:12 ? 次阅读

    golang的MPG调度模型是保障Go语言效率高的一个重要特性,本文详细介绍了Go语言调度模型的设计。

    前言

    Please remember that at the end of the day, all programs that work on UNIX machines end up using C system calls to communicate with the UNIX kernel and perform most of their tasks. 所有在 UNIX 系统上运行的程序最终都会通过 C 系统调用来和内核打交道。

    用其他语言编写程序进行系统调用,方法不外乎两个:一是自己封装,二是依赖 glibc、或者其他的运行库。Go 语言选择了前者,把系统调用都封装到了 syscall 包。封装时也同样得通过汇编实现。

    异步系统调用 G 会和MP分离(G挂到netpoller),同步系统调用 GM 会和P分离(P另寻M),生动的说明了GPM相对GM的精妙之处。

    阻塞

    在 Go 里面阻塞主要分为以下 4 种场景:

    由于原子、互斥量或通道操作调用导致 Goroutine 阻塞,调度器将把当前阻塞的 Goroutine 切换出去,重新调度 LRQ 上的其他 Goroutine;

    由于网络请求和 IO 操作导致 Goroutine 阻塞。Go 程序提供了网络轮询器(NetPoller)来处理网络请求和 IO 操作的问题,其后台通过 kqueue(MacOS),epoll(Linux)或 iocp(Windows)来实现 IO 多路复用。通过使用 NetPoller 进行网络系统调用,调度器可以防止 Goroutine 在进行这些系统调用时阻塞 M。

    这可以让 M 执行 P 的 LRQ 中其他的 Goroutines,而不需要创建新的 M。执行网络系统调用不需要额外的 M,网络轮询器使用系统线程,它时刻处理一个有效的事件循环,有助于减少操作系统上的调度负载。

    当调用一些系统方法的时候(如文件 I/O),如果系统方法调用的时候发生阻塞,这种情况下,网络轮询器(NetPoller)无法使用,而进行系统调用的 G1 将阻塞当前 M1。调度器引入 其它M 来服务 M1 的P。

    如果在 Goroutine 去执行一个 sleep 操作,导致 M 被阻塞了。Go 程序后台有一个监控线程 sysmon,它监控那些长时间运行的 G 任务然后设置可以强占的标识符,别的 Goroutine 就可以抢先进来执行。

    系统调用

    Go 语言通过 Syscall 和 Rawsyscall 等使用汇编语言编写的方法封装了操作系统提供的所有系统调用,其中 Syscall 在 Linux 386 上的实现如下:

    TEXT ·Syscall(SB),NOSPLIT,$0-28

    CALL runtime·entersyscall(SB)

    MOVL trap+0(FP), AX // syscall entry

    MOVL a1+4(FP), BX

    MOVL a2+8(FP), CX

    MOVL a3+12(FP), DX

    MOVL $0, SI

    MOVL $0, DI

    INVOKE_SYSCALL

    CMPL AX, $0xfffff001

    JLS ok

    MOVL $-1, r1+16(FP)

    MOVL $0, r2+20(FP)

    NEGL AX

    MOVL AX, err+24(FP)

    CALL runtime·exitsyscall(SB)

    RET

    ok:

    MOVL AX, r1+16(FP)

    MOVL DX, r2+20(FP)

    MOVL $0, err+24(FP)

    CALL runtime·exitsyscall(SB)

    RET

    Golang - 调度剖析 https://segmentfault.com/a/1190000016611742

    Go: Goroutine, OS Thread and CPU Management https://medium.com/a-journey-with-go/go-goroutine-os-thread-and-cpu-management-2f5a5eaf518a

    Go optimizes the system calls — whatever it is blocking or not — by wrapping them up in the runtime. This wrapper will automatically dissociate the P from the thread M and allow another thread to run on it.

    异步系统调用

    通过使用网络轮询器进行网络系统调用,调度器可以防止 Goroutine 在进行这些系统调用时阻塞M。这可以让M执行P的 LRQ 中其他的 Goroutines,而不需要创建新的M。有助于减少操作系统上的调度负载。

    G1正在M上执行,还有 3 个 Goroutine 在 LRQ 上等待执行

    接下来,G1想要进行网络系统调用,因此它被移动到网络轮询器并且处理异步网络系统调用。然后,M可以从 LRQ 执行另外的 Goroutine。

    最后:异步网络系统调用由网络轮询器完成,G1被移回到P的 LRQ 中。一旦G1可以在M上进行上下文切换,它负责的 Go 相关代码就可以再次执行。

    同步系统调用

    G1将进行同步系统调用以阻塞M1

    调度器介入后:识别出G1已导致M1阻塞,此时,调度器将M1与P分离,同时也将G1带走。然后调度器引入新的M2来服务P。

    b030aa1a-db82-11eb-9e57-12bb97331649.png

    阻塞的系统调用完成后:G1可以移回 LRQ 并再次由P执行。如果这种情况需要再次发生,M1将被放在旁边以备将来使用。

    b03e4c56-db82-11eb-9e57-12bb97331649.png

    sysmon 协程

    b04936ca-db82-11eb-9e57-12bb97331649.jpg

    在 linux 内核中有一些执行定时任务的线程, 比如定时写回脏页的 pdflush, 定期回收内存的 kswapd0, 以及每个 cpu 上都有一个负责负载均衡的 migration 线程等。在 go 运行时中也有类似的协程 sysmon. sysmon 运行在 M,且不需要 P。它会每隔一段时间检查 Go 语言runtime,确保程序没有进入异常状态。

    系统监控的触发时间就会稳定在 10ms,功能比较多:

    检查死锁runtime.checkdead

    运行计时器 — 获取下一个需要被触发的计时器;

    定时从 netpoll 中获取 ready 的协程

    Go 的抢占式调度

    当 sysmon 发现 M 已运行同一个 G(Goroutine)10ms 以上时,它会将该 G 的内部参数 preempt 设置为 true。然后,在函数序言中,当 G 进行函数调用时,G 会检查自己的 preempt 标志,如果它为 true,则它将自己与 M 分离并推入“全局队列”。由于它的工作方式(函数调用触发),在 for{} 的情况下并不会发生抢占,如果没有函数调用,即使设置了抢占标志,也不会进行该标志的检查。

    Go1.14 引入抢占式调度(使用信号的异步抢占机制),sysmon 仍然会检测到运行了 10ms 以上的 G(goroutine)。然后,sysmon 向运行 G 的 P 发送信号(SIGURG)。Go 的信号处理程序会调用P上的一个叫作 gsignal 的 goroutine 来处理该信号,将其映射到 M 而不是 G,并使其检查该信号。gsignal 看到抢占信号,停止正在运行的 G。

    在满足条件时触发垃圾收集回收内存;

    打印调度信息,归还内存等定时任务。

    转自:bert.li@ximalaya.com

    qiankunli.github.io/2020/11/21/goroutine_system_call.html

    编辑:jq

    原文标题:Golang 系统调用与阻塞处理

    文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

    收藏 人收藏
    分享:

    评论

    相关推荐

    使用golang channel的诸多特性和技巧

    ? 本文介绍了使用 golang channel 的诸多特性和技巧,已经熟悉了 go 语言特性的小伙....
    的头像 马哥Linux运维 发表于 09-06 15:14 ? 108次 阅读
    使用golang channel的诸多特性和技巧

    go语言枚举类型怎么用

    go 语言枚举类型是这么用的?在什么场景下会用到枚举?本文对 go 语言枚举做了详细讲解。 枚举,是....
    的头像 马哥Linux运维 发表于 09-02 09:43 ? 172次 阅读

    Go编译器已默认启用-G=3支持泛型

    Go 项目代码仓库昨日提交和合并的一个 PR 显示,Go 语言已在 cmd/compile 中默认启....
    的头像 马哥Linux运维 发表于 09-01 15:52 ? 1194次 阅读
    Go编译器已默认启用-G=3支持泛型

    如何利用Linux终端将图像转换成ASCII艺术?

    想在 Linux 终端中做一些有趣的事情吗?把一张普通的图片转换成 ASCII 艺术怎么样? 你知道....
    的头像 Linux爱好者 发表于 06-29 13:53 ? 357次 阅读

    Go语言凭借什么成为云原生第一语言的?

    偶然看到有人说, Go 语言目前的火爆可能就是昙花一现而已。这个观点我当然是不认同的。 近几年,关于....
    的头像 strongerHuang 发表于 04-22 10:15 ? 941次 阅读
    Go语言凭借什么成为云原生第一语言的?

    详解GO语言的趋势与使用情况

    Go 语言简单易学、性能优良。JetBrains Blog 发布了Go 语言的调查报告,看看GO 语....
    的头像 Linux爱好者 发表于 03-17 11:05 ? 808次 阅读

    Golang:含着金汤匙出生,高并发性能堪比C++

    Python 是一种高级的面向对象的语言。它具有内置的数据结构,结合了动态绑定和类型,是快速开发的理....
    的头像 中科院长春光机所 发表于 11-13 10:20 ? 1140次 阅读

    一份来自Github的2019年Go开发者指南,帮助大家快速入门Go语言

    该指南提供了详细的进阶路线图,列出了学习Go开发所需的各类知识和技能,而且每个知识点也附上啦相应的学....
    的头像 电子发烧友网工程师 发表于 05-05 11:51 ? 4589次 阅读
    一份来自Github的2019年Go开发者指南,帮助大家快速入门Go语言

    GO语言简介!GO是理想的编程语言吗?

    技术实力毋容置疑,不过这哥俩都是玩Kernel的,经历相同,理念相近,分歧会比较少,他们也都坦承C用....
    的头像 电子发烧友网工程师 发表于 04-29 09:47 ? 2198次 阅读
    GO语言简介!GO是理想的编程语言吗?

    Bilibili的网站后台源码被发到了GitHub上?

    当天,B站通过官方微博针对网站工程源代码被泄露一事进行回应,公告称有部分B站工程代码在网上流传,经内....
    的头像 电子发烧友网工程师 发表于 04-24 17:17 ? 25347次 阅读
    Bilibili的网站后台源码被发到了GitHub上?

    Stack Overflow近日发布了2019年度开发者调查报告

    连续 7 年,JavaScript 都位列最受欢迎的编程语言榜首,但值得关注的是,Python 的排....
    的头像 新智元 发表于 04-19 11:03 ? 2375次 阅读
    Stack Overflow近日发布了2019年度开发者调查报告

    Go语言的设计上存在四大“硬伤”

    另外,如果你的列表很长,你要为列表中每个单独的元素生成一个goroutine。正如我之前所说,这本身....
    的头像 新智元 发表于 03-29 08:50 ? 3820次 阅读

    编程语言:开发人员的所爱与所恨

    在全球范围内,胜出者是Google的Go语言——可能是因为使用这种语言的开发人员供不应求。在Hire....
    的头像 IEEE电气电子工程师 发表于 03-11 10:14 ? 2270次 阅读

    Go语言其实有很多优良特性,很多时候都可以代替Python

    但 Go 要想撼动编程界的常青树 Java 二十多年的地位无疑难度颇大。据 HackerRank 数....
    的头像 新智元 发表于 02-13 10:01 ? 3461次 阅读

    Visual Studio Code正在兴起,成为最受欢迎的编辑器

    从该图中我们可以发现Visual Studio Code拥有惊人的17%使用率,去年多个Triple....
    的头像 电子发烧友网工程师 发表于 12-16 10:36 ? 4356次 阅读

    蛰伏5年,Go 2.0终于要来了!

    团队认为此次推出的更新很好,应该能够高效地为用户服务,但更重要的是,这只是一个起点。在使用过程中,仍....
    的头像 新智元 发表于 12-03 09:46 ? 1780次 阅读

    GO语言:简单 动态

    对很多应用来说,编程语言只是简单充当了其与数据集之间的胶水。语言本身的性能常常无关轻重。但是 Str....
    发表于 09-29 11:15 ? 1492次 阅读
    GO语言:简单 动态

    Go语言的开发者正着手准备开发2.0版本,程序员有太多话要说

    对于错误值,第一个问题,就是很难回答上述那些疑问。函数os.IsExist,os.IsNotExis....
    的头像 新智元 发表于 08-31 09:04 ? 4272次 阅读

    如何运用Go语言实现人脸识别

    但是,有一个非??岬幕餮翱?—— dlib 库,一下就吸引了我的注意力。首先,它是用 C ++ ....
    的头像 电子发烧友网工程师 发表于 08-23 09:41 ? 10325次 阅读

    Go语言在多线程领域编程、跨异构平台及编程难易程度的优势

    Go语言的异构平台移植也非常简单,仅需要应用程序的源码,在异构平台上直接编译即可,且编译后的二进制....
    的头像 电子技术应用ChinaAET 发表于 08-14 09:25 ? 4337次 阅读
    Go语言在多线程领域编程、跨异构平台及编程难易程度的优势

    我们在使用Go语言编程之前有什么呢?为什么选择Go语言编程?

    对于我们的案例,Go 语言由于自己的多线程??楹?CPU 可伸缩性获得了较好的性能。无论什么时候我们....
    的头像 悟空智能科技 发表于 07-10 14:19 ? 2865次 阅读

    三大方面对比Go语言和Node.js 谁更有优势

    Node.js与Go语言一直是互联网大战中的主战场,虽说按照普通的各项指标对比,那么这场战争可能在很....
    发表于 06-29 14:59 ? 2722次 阅读

    Python 转向 Go语言的9大原因和3大缺点

    转用一门新语言通常是一项大决策,尤其是当你的团队成员中只有一个使用过它时。今年 Stream 团队的....
    发表于 06-17 07:40 ? 5879次 阅读

    网易有道CEO周枫推荐Go语言并介绍Go语言的3个优点

    网易有道CEO周枫推荐Go语言。他认为Go很好地继承了C语言灵活、简单有效的思想;Go有很高的生产效....
    的头像 新智元 发表于 01-31 14:11 ? 3865次 阅读

    Go语言开发有什么优势?怎么学?

      目前很多IT界的朋友们开始了学习Go这个语言,作为最近几年比较火的服务端开发语言,其开发效率高的特性,使得它迅速的占领...
    发表于 12-19 16:08 ? 1907次 阅读

    D语言,Go语言,Rust语言优势分析

    编者按】本文是D语言来呢后创始人、架构师Andrei Alexandrescu在问答Quora回答在....
    发表于 10-13 11:11 ? 990次 阅读

    以Go绑定实例理解TensorFlow

    本文通过一个简单的Go绑定实例,让读者一步一步地学习到Tensorflow有关ID、作用域、类型等方....
    发表于 09-28 17:42 ? 354次 阅读
    以Go绑定实例理解TensorFlow

    GO语言的??榛兔嫦蚨韵?/a>

    这是关于评论GO语言的第二部分,第一部分:,第三部分会在不日后在CSDN公众号(ID:csdnnew....
    发表于 09-28 17:11 ? 291次 阅读

    GO语言的可靠性和持久性

    作者在本文介绍了Dropbox公司是如何开启探索使用Go语言之路的,在探索的过程中遇到了哪些问题,从....
    发表于 09-28 16:18 ? 1654次 阅读
    GO语言的可靠性和持久性
    日本A级作爱片_日本高清免费毛片大全_国产人妻少妇精品视频_任我爽橹在线精品视频 城市| 呼和浩特市| 包头市| 台中市| 凤庆县| 砚山县| 陆丰市| 青阳县| 无极县| 金川县| 宁武县| 凉城县| 阜南县| 叙永县| 宁晋县| 曲松县| 库伦旗| 满城县| 于田县| 明水县| 仙游县| 镇宁| 昌宁县| 洛隆县| 邹平县| 绍兴县| 西宁市| 喀喇沁旗| 阿尔山市| 陵水| 洱源县| 昂仁县| 澄江县| 会理县| 万山特区| 陆川县| 宜城市| 报价| 阳江市| 鹤山市| 西乌珠穆沁旗| http://444 http://444 http://444 http://444 http://444 http://444