【Golang】sync/once.go源码分析

先看数据结构:

type Once struct {
	done uint32
	m Mutex
}

done indicates whether the action has been performed.
It is first in the struct because it is used in the hot path.
The hot path is inlined at every call site.
Placing done first allows more compact instructions on some architectures (amd64/x86),
and fewer instructions (to calculate offset) on other architectures.
一个互斥锁和一个done标记(表示已做完)。

done其实只需要一个字节,但是却用了uint32,主要是为了保证兼容性。

接下来是一个对外的Do函数:

func (o *Once) Do(f func()) {
	if atomic.LoadUint32(&o.done) == 0 {
		o.doSlow(f)
	}
}

判断是否执行,如果没有就调用doSlow方法。

func (o *Once) doSlow(f func()) {
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}
发布了428 篇原创文章 · 获赞 14 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105496153