码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • Go是如何处理goroutine阻塞的?


    背景

    当我们在go func{}下有如何代码的时候,Go是如何处理阻塞的?

    注:阻塞情况还有其它情况比如 加锁,网络连接读/写,select

     我们需要知道在Go中代码的执行是需要线程(M)绑定 P 才能在CPU上执行

    如果不知道什么是GMP,可以先阅读

    【GMP】当我写下go func的时候,到底发生了什么?_程序员红豆的博客-CSDN博客我们先理解什么是G、M、PG∶goroutine,一个计算任务。由需要执行的代码和其上下文组成,上下文包括∶当前代码位置,栈顶、栈底地址,状态等。M∶ machine,系统线程,执行实体,想要在CPU上执行代码,必须有线程,与C语言中的线程相同,通过系统调用 clone 来创建。P:processor,虚拟处理器,M必须获得P才能执行代码,否则必须陷入休眠(后台监控线程除外),你也可以将其理解为一种 token,有这个 token,才有在物理 CPU核心上执行的权力。Go的调度流程本质上是一个生产-消https://blog.csdn.net/qq_37186127/article/details/125517300?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22125517300%22%2C%22source%22%3A%22qq_37186127%22%7D&ctrtid=DsOjK如果说我们线程在执行的时候阻塞了,那么程序是不是要无限创建线程才能执行?

    答案

    在Go中,这种情况是不会阻塞调度的,而是会把goroutin挂起

    所谓挂起,就是让G进入某个数据结构,待ready后再继续执行,不会占用线程

    线程会进入schedule,继续消费队列,执行其它的G

    什么是schedule?如下图(具体还是看👆🏻的文章【GMP】当我写下go func的时候,到底发生了什么? )

    各种阻塞处理情况

     上述图是Go中各种阻塞的情况下的处理

    以channel举例,对应上图左上角的hchan

    1. type hchan struct {
    2. ……
    3. sendq waitq // list of send waiters
    4. ……
    5. }

    我们来看下在runtime中chan.go的hchan的数据结构

    …… 代表省略了部分结构成员

    sendq是一个waitq类型

    1. type waitq struct {
    2. first *sudog
    3. last *sudog
    4. }

    first和last都是一个sudog类型指针

    Go就是把这些阻塞的G或者sudog挂载到这些数据结构里面

    我们之前说的都是G还有,那sudog是什么?他们之间有什么关系吗?

    一个G可能会对应多个sudog,比如一个G会同时select多个channel

    sysmon:system monitor

    sysmon是什么?我们先来了解一下Go里面的线程

     

     我们在上述图可以看到线程的职责

    gsignal执行信号处理时,切换到gsignal栈

    G0执行runtime调度代码时,切换到m.g0(就是主线程,绿色的那个)

    G 执行用户逻辑时的状态

    而他们都是要绑定P才能执行的,而不需要P就可以执行

    废话一大堆,那sysmon有什么用呢?

    在这篇文章的sysmon之前所谈到的阻塞都是可接管的阻塞

    那也有不可接管的阻塞,比如syscall(系统调用),长时间运行需要剥离P执行

    比如程序中写了如下代码

    GC时需要停止所有goroutine,而老版本的Go的g停止需要主动让出

    什么是主动让出?GO协程(goroutine)的使用

    如果不主动让出,那么GC时就hang死了,

    那么在Go 1.14增加了基于信号的抢占之后,该问题被解决了

    那这个信号的抢占就是由sysmon负责

     上述图片是sysmon的职责

    如果有G运行超过10ms,或者syscall阻塞超过10ms那么久会执行retake操作进行剥离 

    本文完~

  • 相关阅读:
    Java文件目录相关操作
    ​力扣解法汇总515-在每个树行中找最大值
    Java 和低延迟
    Git命令总结
    TR5521设计资料|TR5521替代方案|DP转VGA设计参考
    Java多线程-lambda表达式
    数据结构学习笔记(Ⅳ):串
    【Bioinfomatics】生物信息学名词积累
    从智能家到智慧家!一字之差看到三翼鸟落地差异化
    Medium: 9 Important Things to Remember for AB Test
  • 原文地址:https://blog.csdn.net/qq_37186127/article/details/125519834
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号