返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

4.4.2 闲置

发布于 2024-10-12 19:15:58 字数 1409 浏览 0 评论 0 收藏 0

如果 MP 没找到可执行任务,那么就会进入闲置状态。

// proc.go

func schedule() {
    ...
    
top:
    
    // 尝试 n 种任务查找方式...
    
	if gp == nil {
		gp, inheritTime = findrunnable() // blocks until work is available
	}

	execute(gp, inheritTime)
}
// Finds a runnable goroutine to execute.
// Tries to steal from other P's, get g from local or global queue, poll network.

func findrunnable() (gp *g, inheritTime bool) {

top:

	// local runq ...
	// global runq ...
	// poll network ...
	// steal work from other Ps ...


	// 解除关联 P,放入空闲列表。
	if releasep() != _p_ {
		throw("findrunnable: wrong p")
	}
	pidleput(_p_)

    // 当前 M 休眠。放入闲置列表,直到再次启用。
	stopm()
    
	goto top
}
// Stops execution of the current m until new work is available.
func stopm() {
	_g_ := getg()
    
    // 放入闲置列表。
	mput(_g_.m)
	
    // 休眠。
	mPark()
    
    // 关联由唤醒者提供的 P。
	acquirep(_g_.m.nextp.ptr())
	_g_.m.nextp = 0
}

调度器使用专门的链表管理闲置 M。

// runtime2.go

type schedt struct {
	midle        muintptr // idle m's waiting for work
	nmidle       int32    // number of idle m's waiting for work    
}
// proc.go

// Put mp on midle list.
func mput(mp *m) {
	mp.schedlink = sched.midle
	sched.midle.set(mp)
	sched.nmidle++
}
// Try to get an m from midle list.
func mget() *m {
	mp := sched.midle.ptr()
	if mp != nil {
		sched.midle = mp.schedlink
		sched.nmidle--
	}
	return mp
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文