上卷 程序设计
中卷 标准库
- 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.3 唤醒
每当有新 G 创建,调度器都会积极尝试其他 MP 并发执行。
// proc.go func newproc(fn *funcval) { newg := newproc1(fn, gp, pc) runqput(_p_, newg, true) if mainStarted { wakep() } }
// Tries to add one more P to execute G's. func wakep() { // 没有空闲 P,放弃。 if atomic.Load(&sched.npidle) == 0 { return } // 某些 MP 正在积极查找任务,也就是自旋状态。 // 某些 M 新建或刚唤醒,还没开始找任务,也是自旋状态。 if atomic.Load(&sched.nmspinning) != 0 || !atomic.Cas(&sched.nmspinning, 0, 1) { return } startm(nil, true) }
// 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。 if _p_ == nil { _p_ = pidleget() if _p_ == nil { return } } // 获取闲置 M,或新建。 nmp := mget() if nmp == nil { // 关联函数 mspinning,用于设置自旋状态。 var fn func() if spinning { // The caller incremented nmspinning, so set m.spinning in the new M. fn = mspinning } // 新建。 newm(fn, _p_, id) return } // 设置自旋状态,以及待关联 P。 nmp.spinning = spinning nmp.nextp.set(_p_) // 唤醒,重新开始调度循环。 notewakeup(&nmp.park) }
设置自旋状态,可避免短时间内激活多个 MP 去竞争任务。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论