xiaohanliang
Golang
Golang
  • review
  • DATA STRUCT
    • Slice
    • Map
    • Lock
    • Chanel
    • Pool
    • Interface
  • SCHEDULE
    • 为什么要设计Go协程
    • GMP都是干什么的
    • 一次完整的调度
    • 什么是G栈
    • P&M剥离
    • 常见的暂停操作
  • OTHERS
    • GC介绍
    • 内存介绍
    • 内存分析
Powered by GitBook
On this page

Was this helpful?

  1. SCHEDULE

常见的暂停操作

  • GoSched - 见于抢占调度

    • 这种操作会把当前G状态从running改回runnable,再放回全局队列里, 自己则是通过一次Schedule再找个任务做

  • GoPark - 见于WaitGroup

    • 与GoSched差不多, 都是要把状态改成runable以后自己通过sched找个任务做, 区别是被拿下来的G并不会被被放到队列里, 如果你不主动去再重启它的话它永远也不会再运行了

    • 运行它的办法是GoReady函数, 这个函数会直接让G去往P的run_next位置

  • Notesleep - 见于休眠的M:stopm()

    • 之前两种都是围绕G展开的, 这一种则是针对线程的, 整个线程直接被冻结, 直到被notewakeup函数叫醒

    • 被认为是"很灵活", 使用FUTEX技术实现

  • StopTheWorld - 见于GC

    • 名气太大不用介绍, 关于stw的代码其实在调度过程里穿插的到处都是, 目的是让调度过程尽早响应GC停止一切的命令. 所有的G该停就停,M改休眠的休眠, 这种操作是怎么做到的呢?

    • 停G: 通过设置抢占位(stackpreempt/复习G栈内容), 使得G在下一次函数调用的时候进入morestack开始状态检查, 进而GC沉睡

    • 停M: 设置全局变量gcwaiting=1这个变量会在M下一次执行schedule()的时候发挥作用, 让M进入沉睡状态

    • 停P: 将所有的P,包含空闲的,以及正在SYSCALL的P全都暂停, 遍历全局P列表,schedt.allp[i],逐一发送抢占信号

    • 最后会通过StartTheWorld再将所有P叫起来工作, 原则是找到这个P之前所关联的M, 将这个沉睡的M叫起来, 如果这个P之前没关联M, 那么就创建一个新M来接纳P

PreviousP&M剥离NextGC介绍

Last updated 4 years ago

Was this helpful?