上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
4.4.2 唤醒
在唤醒其他 MP 出来工作前,先检查是否有处于自旋状态的 MP。
// proc.go // Tries to add one more P to execute G's. // Called when a G is made runnable (newproc, ready). func wakep() { // 必须有闲置的 P。 if atomic.Load(&sched.npidle) == 0 { return } // 如果失败,表示有处于自旋状态的 M/P。 if atomic.Load(&sched.nmspinning) != 0 || !atomic.Cas(&sched.nmspinning, 0, 1) { return } startm(nil, true) }
用 wakep 唤醒或新建 M 时,会设置自旋状态。表示当前 MP 正积极查找 runnable G,其他人就不要掺合了。
自旋状态要么被 schedule 调用 resetspinning 解除,要么类似 findrunnable 在 stopm 前自行解除。
新建(newm)以初始化函数(mspinning)设置自旋状态;被唤醒的,在 startm 中直接设置。
// proc.go // Schedules some M to run the p (creates an M if necessary). // If p==nil, tries to get an idle P, if no idle P's does nothing. func startm(_p_ *p, spinning bool) { // 如果没有传入 P,则试图绑定空闲 P。 if _p_ == nil { _p_ = pidleget() // 没有空闲 P,解除自旋计数,放弃本次唤醒。 if _p_ == nil { if spinning { atomic.Xadd(&sched.nmspinning, -1) } return } } // 获取休眠 M。 mp := mget() // 获取失败,新建。 if mp == nil { // 线程初始化函数,用于设置自旋状态。 var fn func() if spinning { fn = mspinning } newm(fn, _p_, id) return } // 传递 P,唤醒休眠的 M。 mp.spinning = spinning mp.nextp.set(_p_) notewakeup(&mp.park) }
func mspinning() { getg().m.spinning = true }
nextp
M 有 p 和 nextp 两个属性。
M.p 是正式绑定;nextp 临时存储,稍后绑定。
// runtime2.go type m struct { p puintptr // attached p for executing go code (nil if not executing go code) nextp puintptr }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论