golang sync.Once 保证某个动作仅执行一次的机制
type Once struct { done atomic.Uint32 m Mutex }
sync.Once 是 Go 语言标准库 sync 包中的一个类型,用于确保某个操作(函数)只被执行一次。
这对于初始化操作非常有用,比如数据库连接的建立、日志文件的打开等,这些操作通常只需要在程序启动时执行一次。
sync.Once 只有一个公开方法 Do(f func()),这个方法接受一个无参数且无返回值的函数作为参数。
当 Do 第一次被调用时,它会执行传入的函数 f,并设置一个内部标记表示该函数已经被执行过了。
之后对 Do 的任何调用都不会再执行 f,即使是从多个 Goroutine 并发调用也是如此。
* “Once类型” (type Once struct{xxx})包含一个done原子类型和一个m互斥锁。done用于标记初始化函数是否已经执行过。
* “Do方法” 接受一个无参数的函数 f 作为输入,如果 Once 的 done 值为0(即初始化函数尚未执行),则调用 doSlow 方法执行函数 f。
* “doSlow方法” 首先加锁,确保同时只有一个协程能执行初始化函数。然后检查 done 值,如果为0,则执行函数 f,并在 defer 语句中设置 done 为1,以标记初始化函数已完成。最后解锁。
这个实现确保了即使在多协程环境下,初始化函数也只会被执行一次,并且能够处理并发调用 Do 方法的情况。
golang oncefunc.go 的 OnceFunc 和 once.go Do 的区别。