Go maps无法通过并发测试。

huangapple go评论102阅读模式
英文:

Go maps fails the concurency test

问题

当我运行以下代码时:

  1. import (
  2. "log"
  3. "sync"
  4. "testing"
  5. "time"
  6. )
  7. func TestConcurrency(t *testing.T) {
  8. var mutex sync.RWMutex
  9. dictionary := make(map[interface{}]interface{})
  10. go func() {
  11. var value interface{}
  12. for {
  13. go func() {
  14. mutex.Lock()
  15. dictionary["Key"] = ""
  16. mutex.Unlock()
  17. }()
  18. go func() {
  19. mutex.RLock()
  20. value = dictionary["Key"]
  21. mutex.RUnlock()
  22. }()
  23. }
  24. log.Println(value)
  25. }()
  26. }

使用:

  1. go test -race fileName.go

结果是:

  1. 发现1个数据竞争
  2. 我该如何解决这个问题?
  3. 我有很多并发的写入和读取操作。
英文:

When I run the following code:

  1. import (
  2. "log"
  3. "sync"
  4. "testing"
  5. "time"
  6. )
  7. func TestConcurrency(t *testing.T) {
  8. var mutex sync.RWMutex
  9. dictionary := make(map[interface{}]interface{})
  10. go func() {
  11. var value interface{}
  12. for {
  13. go func() {
  14. mutex.Lock()
  15. dictionary["Key"] = ""
  16. mutex.Unlock()
  17. }()
  18. go func() {
  19. mutex.RLock()
  20. value = dictionary["Key"]
  21. mutex.RUnlock()
  22. }()
  23. }
  24. log.Println(value)
  25. }()
  26. }

using :

  1. go test -race fileName.go

It results in:

  1. Found 1 data race(s)

How can I solve this?

I have many concurrent writes and reads.

答案1

得分: 4

如果你查看竞争检测器报告的错误,你会发现它报告了在value = dictionary["Key"]这一行上的并发写操作,这意味着检测到的竞争是在value而不是dictionary上。

你同时访问了两个变量,dictionaryvalue。你不能使用读锁来保护对映射的读取和对value变量的写入。你要么需要第二个互斥锁,要么需要始终使用mutex.Lock来串行访问这两个变量。

英文:

If you look at the error presented by the race detector, you would see that it reported concurrent writes on the value = dictionary["Key"] line, meaning the race being detected is on value, not dictionary.

You are concurrently accessing 2 variables, dictionary and value. You can't use the read lock to protect reads on the map, and writes to the value variable. You either need a second mutex, or you need to always use mutex.Lock to serialize access to both variables.

答案2

得分: 0

这段代码将正常工作:

  1. go func() {
  2. mutex.Lock()
  3. value = dictionary["Key"]
  4. mutex.Unlock()
  5. }()

它保护变量value免受并发写入的影响。

英文:

This code will work correctly:

  1. go func() {
  2. mutex.Lock()
  3. value = dictionary["Key"]
  4. mutex.Unlock()
  5. }()

It protects the variable value from concurrent write.

huangapple
  • 本文由 发表于 2017年3月15日 22:56:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/42813322.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定