sync.Once

once结构是这样的

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()
    }
}

作用是保证多个协程只执行某个函数一次
为什么不能使用CAS原子操作来替代锁呢?

if atomic.CompareAndSwapUint32(&o.done, 0, 1){
    f()
}

在多线程调用如下代码的情况下

once.DO(a)
b()

若用原子操作,多线程情况下,执行b的时候,a并不一定成功执行(可能第一次调用Do的线程正在执行中,别的线程再调用会直接返回,造成并未成功执行a的情况下执行b)

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容