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

P&M剥离

常见的一些系统调用函数如syscall.Chown()本质上是调用syscall()的函数完成的, 在go语言中执行一次系统调用包含准备工作+调用+收尾工作三步.

准备工作是指保存现场(详细的说就是pc/sp指针), 同时将P+G的状态从RUNNING调整成SYSCALL的状态, 然后最重要的是确保监控协程sysmon正在运行("什么是sysmon呀?")

Ok, 整理一下现场, M被派去执行G的系统调用任务, P在旁边围观. 我们都知道系统调用时间可能很长, 太长了以至于把P放在那边看都有点不合适了, 这就相当于P无所事事. 但是问题是系统调用时间要多长你知不知道?

  • 如果事先知道就耗时很短

    • 调用结束直接回来当做什么都没发生过

  • 如果事先就知道耗时很长

    • 不能把P放在这里就这么等着, 于是经典场面再放送: P_handoff! 我们会在系统调用一开始的时候就直接把P摘下来

    • 如果P中有任务, 唤醒一个M来执行这个任务. 如果P中无任务, 放到P空闲池内

  • 抱歉, 不知道, 以为很短没想到花了这么长时间

    • sysmon上场了, sysmon是一个监控线程, 如果它发现你这个调用怎么花了这么长时间, 会帮你把P摘下来

    • 所以sysmon很重要, 如果你一个系统调用花了这么久, 然后你P里的任务都没执行, 那就糟了

所以等你回来的时候, (时间很短的话)可能M手上还有P, (时间很久的话)M手上就没有P了, 因为自己主动交走了, 或者被sysmon强制搞走了.

  • 找找看之前关联的P, 看看这个能不能用, 也许被摘走了但是没被别的M占用

  • 如果之前的用不了, 尝试找找看空闲池里有没有能用的

如果这个M真倒霉到最后也没能找到一个P, 准备休眠吧, 但是自己手上还有一个刚刚系统调用回来的G, 这时候会把这个G放到全局队列里, 然后自己休眠去了.

Previous什么是G栈Next常见的暂停操作

Last updated 4 years ago

Was this helpful?