go的设计者认为,如果需要重入锁,就说明你的代码写的有问题: https://stackoverflow.com/questions/14670979/recursive-locking-in-go#14671462
可以将代码按照作用范围分层,金字塔形,底部是各个小函数,上层调用下层的函数,越往上作用范围越大;各层有自己的锁,并只能在本层的函数中使用:同一个锁在不同层中使用就会导致重入
go的标准库里面的做法是将需要锁住的操作独立为函数`并以Locked为后缀命名`,然后在调用这些函数的地方用锁来保护:
func (b *body) Read(p []byte) (n int, err error) {
b.mu.Lock()
defer b.mu.Unlock()
if b.closed {
return 0, ErrBodyReadAfterClose
}
return b.readLocked(p)
}
// Must hold b.mu.
func (b *body) readLocked(p []byte) (n int, err error) {
if b.sawEOF {
return 0, io.EOF
}
n, err = b.src.Read(p)
...
}
如果一定要实现可重入锁,就必须有类似goroutine id的东西,这可能也是go的设计者不提供goroutine id的原因
#1