once結(jié)構(gòu)是這樣的
type Once struct {
m Mutex
done uint32
}
其中只有這么一個方法
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path.
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 {
defer atomic.StoreUint32(&o.done, 1)
f()
}
}
作用是保證多個協(xié)程只執(zhí)行某個函數(shù)一次
為什么不能使用CAS原子操作來替代鎖呢宴咧?
if atomic.CompareAndSwapUint32(&o.done, 0, 1){
f()
}
在多線程調(diào)用如下代碼的情況下
once.DO(a)
b()
若用原子操作徙硅,多線程情況下波附,執(zhí)行b的時候,a并不一定成功執(zhí)行(可能第一次調(diào)用Do的線程正在執(zhí)行中,別的線程再調(diào)用會直接返回骂束,造成并未成功執(zhí)行a的情況下執(zhí)行b)