如何锁定地图并修复数据竞争
How to lock Map and fix data race
我正在尝试解决警告:数据竞争
这是代码:
package models
import (
"sync"
"time"
)
type Stats struct {
sync.Mutex
request map[int64]int
}
func (s *Stats) PutRequest() {
s.Lock()
s.request[time.Now().Unix()]++
s.Unlock()
}
func (s *Stats) GetRequests() map[int64]int {
s.Lock()
m := s.request
s.Unlock()
return m
}
var Requests = Stats{
sync.Mutex{},
make(map[int64]int),
}
如果我将 Stats 字段请求更改为整数,则一切正常,但不适用于地图。 Go中如何正确锁定地图?
GetRequests
returns 对映射的引用,因此如果其他代码调用该函数并在返回的映射上执行 r/w 而未获取锁,则会引入数据竞争
使用sync.RWMutex
func (s *Stats) PutRequest(ut int64) {
s.Lock()
defer s.Unlock()
s.request[ut]++
}
func (s *Stats) GetRequests() map[int64]int {
s.RLock()
defer s.RUnlock()
m := make(map[int64]int, len(s.request))
for k, v := range s.request {
m[k] = v
}
return m
}
在这种情况下,以下频道示例可能很有趣。 go by example - stateful goroutines
无论如何你需要在返回之前复制地图。
我正在尝试解决警告:数据竞争 这是代码:
package models
import (
"sync"
"time"
)
type Stats struct {
sync.Mutex
request map[int64]int
}
func (s *Stats) PutRequest() {
s.Lock()
s.request[time.Now().Unix()]++
s.Unlock()
}
func (s *Stats) GetRequests() map[int64]int {
s.Lock()
m := s.request
s.Unlock()
return m
}
var Requests = Stats{
sync.Mutex{},
make(map[int64]int),
}
如果我将 Stats 字段请求更改为整数,则一切正常,但不适用于地图。 Go中如何正确锁定地图?
GetRequests
returns 对映射的引用,因此如果其他代码调用该函数并在返回的映射上执行 r/w 而未获取锁,则会引入数据竞争
使用sync.RWMutex
func (s *Stats) PutRequest(ut int64) {
s.Lock()
defer s.Unlock()
s.request[ut]++
}
func (s *Stats) GetRequests() map[int64]int {
s.RLock()
defer s.RUnlock()
m := make(map[int64]int, len(s.request))
for k, v := range s.request {
m[k] = v
}
return m
}
在这种情况下,以下频道示例可能很有趣。 go by example - stateful goroutines
无论如何你需要在返回之前复制地图。