I'm logging every second the length of a map; I don't care if I have the "exact" value / race conditions (off by one is ok). I'm interested to know if this could cause a panic and if I have to enclose len()
with some .RLock()/Unlock()
or not.
I'm asking because concurrent reads/writes in a map will cause a panic (Go detects that) but I don't know if reading the length counts as a "read". I have tried with a test program but cannot produce a crash but I'd rather have an exact answer, at least for the sake of it.
If it matters I'm interested in both len for arrays and for maps. Thanks!
To understand what this means, we need to first understand what is a Go channel? A channel is the Go way of implementing communication between goroutines. It's essentially a thread-safe data pipe that allows goroutines to send or receive data among themselves without having to access a shared memory block.
In Go no value is safe for concurrent read/write, slices (which are slice headers) are no exception.
It's important to note that maps in go are not safe for concurrent use. Maps are not safe for concurrent use: it's not defined what happens when you read and write to them simultaneously.
It's used so that when one thread (or goroutine in the case of Golang) is accessing a value inside a memory address, it can lock out the other threads so they have to wait in line. This guarantees that there will not be any of this random accessing and changing of values.
It is a race condition. The results are undefined. For example,
racer.go
:
package main
func main() {
m := make(map[int]int)
l := 0
go func() {
for {
l = len(m)
}
}()
for i := 0; i < 10000; i++ {
m[i] = i
}
}
Output:
$ go run -race racer.go
==================
WARNING: DATA RACE
Read at 0x00c00008e000 by goroutine 5:
main.main.func1()
/home/peter/gopath/src/racer.go:8 +0x5f
Previous write at 0x00c00008e000 by main goroutine:
runtime.mapassign_fast64()
/home/peter/go/src/runtime/map_fast64.go:92 +0x0
main.main()
/home/peter/gopath/src/racer.go:12 +0xba
Goroutine 5 (running) created at:
main.main()
/home/peter/gopath/src/racer.go:6 +0x92
==================
Found 1 data race(s)
exit status 66
$
References:
Wikipedia: Race condition
The Go Blog: Introducing the Go Race Detector
Go: Data Race Detector
Benign Data Races: What Could Possibly Go Wrong?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With