在 go 中延迟互斥锁解锁时,您会遇到数据竞争吗?

Can you get a data race when deferring a mutex unlock in go?

此 Get 方法是否存在错误并且容易出现理论上的数据争用?

type item struct {
    val   int
    mutex sync.RWMutex
}

func (i *item) Set(val int) {
    i.mutex.Lock()
    defer i.mutex.Unlock()
    i.val = val
}

func (i *item) Get() int {
    i.mutex.RLock()
    defer i.mutex.RUnlock()
    return i.val
}

我问是因为 运行 我用 -race 测试以前的代码时,我看到了罕见的数据竞争,但找不到任何方法来复制效果。

是否可以将 i.val 设置为不同的值,在 defer 执行 RUnlock 时和我们从结构中读取 return 值时?

Get() 必须是这样的吗?:

func (i *item) Get() int {
    i.mutex.RLock()
    defer i.mutex.RUnlock()
    val := i.val
    return val
}

您的代码是安全的,延迟函数在 return 语句的表达式列表被求值后执行。如果你有 named result parameters,return 值也会在调用延迟函数之前分配给它们(你甚至可以在 "truly" [=18] 之前修改 return 值=]从封闭函数中调用)。

无需创建局部变量来存储i.val