我正在进行一个比互斥锁更适合自旋锁的项目,经过几次尝试之后,我想出了如下几点:
type SpinLock uint32
func (sl *SpinLock) Lock() {
for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
runtime.Gosched() //without this it locks up on GOMAXPROCS > 1
}
}
func (sl *SpinLock) Unlock() {
atomic.StoreUint32((*uint32)(sl), 0)
}它工作得很好,甚至比sync.Mutex快一点点,是sync.RWMutex速度的2倍。
➜ go test -bench=. -benchmem -v -cpu 4
BenchmarkSpinL-4 2000 1078798 ns/op 33923 B/op 2006 allocs/op
BenchmarkMutex-4 2000 1195814 ns/op 32781 B/op 2002 allocs/o
BenchmarkRWMutex-4 1000 2352117 ns/op 78253 B/op 2147 allocs/op该测试使用多个读取器/写入器来编写map[int]*struct{int, int}。使用-race运行它也不会检测到任何数据竞争。
但我有一种唠叨的感觉,我忘了一些东西,所以我想知道我的实现是否正确?
发布于 2014-09-27 13:44:38
唯一的弱点是执行不安全,也没有确保拷贝保护的机制。我会隐藏它的底层类型并返回为sync.Locker,这样它就不会被误用:
type spinLock uint32
func (sl *spinLock) Lock() {
for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
runtime.Gosched() //without this it locks up on GOMAXPROCS > 1
}
}
func (sl *spinLock) Unlock() {
atomic.StoreUint32((*uint32)(sl), 0)
}
func SpinLock() sync.Locker {
return &spinLock{}
}我在sync.Cond中看到的另一种选择是嵌入用于复制保护的辅助类型,尽管这会使实现变得更加复杂。
https://codereview.stackexchange.com/questions/60332
复制相似问题