Go map and concurrency security issues
It is unsafe for code in different goroutines to read and write to the same map
simultaneously. The map
values themselves may become inconsistent due to these operations, and related programs may experience unpredictable issues.
We can demonstrate the concurrency safety problem with map
using the following code:
package main
func main() {
m := make(map[int]int)
go func() {
for {
_ = m[1]
}
}()
go func() {
for {
m[2] = 2
}
}()
select {}
}
The error message is: fatal error: concurrent map read and map write.
If you check the Go source code: hashmap_fast.go#L118, you’ll see that during reads, the hashWriting
flag is checked, and if this flag is set, a concurrency error is reported.
The flag is set during writes: hashmap.go#L542
h.flags |= hashWriting
After setting, the flag is cleared: hashmap.go#L628
There are also several other checks for concurrent read and write issues in the code, such as checking for concurrent writes, similar issues when deleting keys, and concurrency problems during iteration.
Sometimes, concurrency issues with map
are not easily detected; you can use the -race
flag to check.
So, how can we ensure concurrency safety for map
?
Click Read More for the full article.