在代码中看到使用sync.Once,查了一下资料,
go使用锁保证once.Do(f)中f只执行一次
想到了以前C++中设计模式的单例模式
sync once.go
type Once struct {
m Mutex // 互斥锁
done uint32 // 用来表示只执行一次
}
func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 1 { //表明已经执行过了
return
}
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 {
defer atomic.StoreUint32(&o.done, 1) // 执行f后增加计数
f()
}
}
使用
var once sync.Once
once.Do(f) 即使once多次调用Do,f只执行一次
注意:即使f 调用crash,Do也会认为f调用过了