简体   繁体   中英

Go RWMutex still raises race condition?

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\n", 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
==================

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\n", 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM