Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is len() thread safe in golang?

Tags:

go

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!

like image 639
Thomas Avatar asked Oct 08 '18 22:10

Thomas


People also ask

Are Go channels thread-safe?

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.

Are Golang slices thread-safe?

In Go no value is safe for concurrent read/write, slices (which are slice headers) are no exception.

Are maps concurrency safe Golang?

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.

What is thread safety in Golang?

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.


1 Answers

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?

like image 126
peterSO Avatar answered Sep 27 '22 19:09

peterSO