sync.Once.Do 的实现:
type Once struct {
// 为了防止多个协程同时执行,加入锁
m Mutex
// 记录是否被执行过,最终会被atomic.StoreUnit32存起来
done uint32
}
func (o *Once) Do(f func()) {
// 如果执行过就return
if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path. 加锁
o.m.Lock()
// 最后解锁
defer o.m.Unlock()
// 如果没有执行,就执行f(),在此代码块的最后存储执行过的标记
if o.done == 0 {
defer atomic.StoreUint32(&o.done, 1)
f()
}
}