doumeilmikv7099 2019-05-03 05:57
浏览 56

为什么要同步?一旦在doSlow()中使用atomic?

I have a question about Once.doSlow(). The source code of Once is below:

// Once is an object that will perform exactly one action.
type Once struct {
    // 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 uint32
    m    Mutex
}

// Do calls the function f if and only if Do is being called for the
// first time for this instance of Once. In other words, given
//  var once Once
// if once.Do(f) is called multiple times, only the first call will invoke f,
// even if f has a different value in each invocation. A new instance of
// Once is required for each function to execute.
//
// Do is intended for initialization that must be run exactly once. Since f
// is niladic, it may be necessary to use a function literal to capture the
// arguments to a function to be invoked by Do:
//  config.once.Do(func() { config.init(filename) })
//
// Because no call to Do returns until the one call to f returns, if f causes
// Do to be called, it will deadlock.
//
// If f panics, Do considers it to have returned; future calls of Do return
// without calling f.
//
func (o *Once) Do(f func()) {
    if atomic.LoadUint32(&o.done) == 0 {
        // Outlined slow-path to allow inlining of the fast-path.
        o.doSlow(f)
    }
}

func (o *Once) doSlow(f func()) {
    o.m.Lock()
    defer o.m.Unlock()
    if o.done == 0 {
        defer atomic.StoreUint32(&o.done, 1)
        f()
    }
}

Q: After a goroutine get the lock in doSlow(), why using atomic instead of directly let o.done = 1, like below:

if o.done == 0 {
    defer func(){o.done = 1}()
    f()
}

Thanks for help.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥20 mysql架构,按照姓名分表
    • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
    • ¥15 Macbookpro 连接热点正常上网,连接不了Wi-Fi。
    • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
    • ¥15 linux驱动,linux应用,多线程
    • ¥20 我要一个分身加定位两个功能的安卓app
    • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
    • ¥15 IAR程序莫名变量多重定义
    • ¥15 (标签-UDP|关键词-client)
    • ¥15 关于库卡officelite无法与虚拟机通讯的问题