dongshang5862 2018-03-21 02:58 采纳率: 0%
浏览 41
已采纳

RWMutex仍会提高比赛条件吗?

I have a seemingly innocent package that just makes a slice and protects it with a RWMutex. However, when I run it, it still complains about a race condition. What am I doing wrong? (playground)

type Ids struct {
    e []int64
    sync.RWMutex
}

func (i *Ids) Read() []int64 {
    i.RLock()
    defer i.RUnlock()

    return i.e
}


func (i *Ids) Append(int int64) {
    i.Lock()
    defer i.Unlock()

    i.e = append(i.e, int)
}

func main() {
    t := &Ids{e: make([]int64, 1)}

    for i := 0; i < 100; i++ {
        go func() {
            fmt.Printf("%v
", t.Read())
        }()

        go func() {
            t.Append(int64(i))
        }()
    }

    time.Sleep(time.Second * 10)
}

when run with -race, it returns (among other things):

==================
WARNING: DATA RACE
Read at 0x00c4200a0010 by goroutine 7:
  main.main.func2()
      .../main.go:38 +0x38

Previous write at 0x00c4200a0010 by main goroutine:
  main.main()
      .../main.go:32 +0x197

Goroutine 7 (running) created at:
  main.main()
      .../main.go:37 +0x173
==================
  • 写回答

1条回答 默认 最新

  • dongyuan9149 2018-03-21 03:06
    关注

    You are capturing the same variable i in multiple goroutines.

    One way to fix this is to modify your main for loop like so:

    for i := 0; i < 100; i++ {
        i := i  # look here
        go func() {
            fmt.Printf("%v
    ", t.Read())
        }()
    
        go func() {
            t.Append(int64(i))
        }()
    }
    

    This will ensure that you capture a different variable in the closure of the second goroutine each iteration of the for loop. In your example, the i passed to t.Append was the same i that was incremented by the for loop concurrently.

    I also recommend running go vet to catch such errors in the future. For more information, there is an entry on this problem in the Go FAQ that goes into more detail: https://golang.org/doc/faq#closures_and_goroutines

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!