《Go 语言原本》

9.1 运行时死锁检查

原理:

$$ m - midle - miclelocked - msys > 0 $$

只检查是否所有的工作线程都已休眠

缺点:

当存在可运行的 goroutine 时,系统监控死锁检测不会认为发生阻塞 运行时只检查 goroutine 是否在 Go 并发原语中被阻止,不考虑等待其他系统资源的 goroutine。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
//go:nowritebarrierrec
func mput(mp *m) {
	mp.schedlink = sched.midle
	sched.midle.set(mp)
	sched.nmidle++
	checkdead()
}
//go:nowritebarrierrec
func mget() *m {
	mp := sched.midle.ptr()
	if mp != nil {
		sched.midle = mp.schedlink
		sched.nmidle--
	}
	return mp
}

sched.nmidlelocked:

1
2
3
4
5
6
7
8
func incidlelocked(v int32) {
	lock(&sched.lock)
	sched.nmidlelocked += v
	if v > 0 {
		checkdead()
	}
	unlock(&sched.lock)
}