两个原子样式的代码在sync/atomic.once.go中是否是必需的?

huangapple go评论73阅读模式
英文:

Is the two atomic style code in sync/atomic.once.go necessary?

问题

sync/atomic.once.go中的代码是:

func (o *Once) Do(f func()) {
    if atomic.LoadUint32(&o.done) == 1 { //A
    //if o.done == 1 {
        return
    }
    // Slow-path.
    o.m.Lock()
    defer o.m.Unlock()
    if o.done == 0 {
        f()
        atomic.CompareAndSwapUint32(&o.done, 0, 1) //B
        //o.done = 1
    }
}

我认为上面的A、B两个原子式的代码是不必要的或者没有用处的。
我认为锁已经足够了,如果A、B不是原子式的也可以。
我一定是漏掉了什么,请告诉我A、B代码的目的。
谢谢。

英文:

The code in sync/atomic.once.go is :

func (o *Once) Do(f func()) {
		if atomic.LoadUint32(&o.done) == 1 { //A
		//if o.done == 1 {
			return
		}
		// Slow-path.
		o.m.Lock()
		defer o.m.Unlock()
		if o.done == 0 {
			f()
			atomic.CompareAndSwapUint32(&o.done, 0, 1) //B
			//o.done = 1
		}
	}

I don't think the two 'atomic-style' code A,B above is necessary or useful.
I think the lock is enough, and it could be ok if A,B are not atomic style.
I must miss something, please be kind to tell me the purpose of the code A,B.
Thank you.

答案1

得分: 4

原始的是正确的。原因是Go的内存模型规定,如果没有同步(if o.done == 1),对o.done的更改可能根本不会被观察到。

英文:

The original is correct. The reason is that the Go Memory Model says, that without synchronization (if o.done == 1) the changes to o.done might not be observed at all.

huangapple
  • 本文由 发表于 2013年2月27日 23:14:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/15115589.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定