首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自旋锁实现

自旋锁实现
EN

Code Review用户
提问于 2014-08-18 00:08:43
回答 1查看 946关注 0票数 9

我正在进行一个比互斥锁更适合自旋锁的项目,经过几次尝试之后,我想出了如下几点:

代码语言:javascript
复制
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倍。

代码语言:javascript
复制
➜ 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运行它也不会检测到任何数据竞争。

但我有一种唠叨的感觉,我忘了一些东西,所以我想知道我的实现是否正确?

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-09-27 13:44:38

唯一的弱点是执行不安全,也没有确保拷贝保护的机制。我会隐藏它的底层类型并返回为sync.Locker,这样它就不会被误用:

代码语言:javascript
复制
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中看到的另一种选择是嵌入用于复制保护的辅助类型,尽管这会使实现变得更加复杂。

票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/60332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档