dongwuxie5112
2018-03-01 10:39
浏览 36
已采纳

推迟进行互斥锁解锁时,您能否获得数据竞赛?

Is this Get method buggy and prone to a theoretical data race?

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
}

I ask because I saw a rare data race when running my tests with -race with the former code, but can't find any way of duplicating the effect.

Is it possible for i.val to be set to a different value between when the defer carries out the RUnlock, and when we read and return the value from the struct?

Must Get() be something like this instead?:

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

图片转代码服务由CSDN问答提供 功能建议

此Get方法是否存在错误并且容易发生理论上的数据争夺?

  类型项struct {
 val int 
 Mutex sync.RWMutex 
} 
 
func(i * item)Set(val int){
 i.mutex.Lock()
延迟i.mutex  .Unlock()
 i.val = val 
} 
 
func(i * item)Get()int {
 i.mutex.RLock()
推迟i.mutex.RUnlock()
返回 i.val 
} 
   
 
 

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

是否可以将i.val设置为延迟执行RUnlock的时间与我们执行此操作之间的其他值。 读取并从结构返回值?

必须使用Get()代替吗?:

  func(i * item  )Get()int {
 i.mutex.RLock()
延迟i.mutex.RUnlock()
 val:= i.val 
 return val 
} 
    
 
  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongyukang7006 2018-03-01 10:42
    已采纳

    Your code is safe, deferred functions are executed after the expression list of the return statement is evaluated. If you would have named result parameters, the return values would also be assigned to them before calling the deferred functions (and you could even modify the return values before "truly" returning from the enclosing function).

    No need to create a local variable to store i.val.

    已采纳该答案
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题