[Golang] sync / once.go source code analysis

First look at the data structure:

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 actually only needs one byte, but uint32 is used, mainly to ensure compatibility.

Next is an external Do function:

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

Determine whether to execute, if not, call the doSlow method.

func (o *Once) doSlow(f func()) {
	o.m.Lock()
	defer o.m.Unlock()
	if o.done == 0 {
		defer atomic.StoreUint32(&o.done, 1)
		f()
	}
}
Published 428 original articles · Liked 14 · Visitors 100,000+

Guess you like

Origin blog.csdn.net/LU_ZHAO/article/details/105496153