Is it thread safe to concurrently read/access an array in go?

120

Question: Is it thread safe to concurrently read/access an array in go?

Like if I have a struct with an array and I want to do something like this

type Paxos struct {     peers      []string }  for _, peer := range px.peers {    \\do stuff } 

My routines/threads will never modify the peers array, just read from go error it. Peers is an array of server addresses, and servers may fail but that wouldn't affect the peers array (later rpc calls would just fail)

Total Answers: 2

9

Answers 1: of Is it thread safe to concurrently read/access an array in go?

If no writes are involved, concurrent reads are always safe, regardless of the data structure. However, as soon as even a single concurrency-unsafe write to a variable is involved, you need to serialise concurrent access (both writes and reads) to the variable.


Moreover, you can safely write to elements of a slice or go error an array under the condition that no more than one goroutine write to a given element.

For instance, if you run the following programme with the race detector on, it's likely to report a race condition, because multiple goroutines concurrently modify variable results without precautions:

package main  import (     "fmt"     "sync" )  func main() {     const n = 8     var results []int     var wg sync.WaitGroup     wg.Add(n)     for i := 0; i < n; i++ {         i := i         go func() {             defer wg.Done()             results = append(results, square(i))         }()     }     wg.Wait()     fmt.Println(results)  }  func square(i int) int {     return i * i } 

However, the following programme contains no such no synchronization bug, because each element of the slice is modified by a single goroutine:

package main  import (     "fmt"     "sync" )  func main() {     const n = 8     results := make([]int, n)     var wg sync.WaitGroup     wg.Add(n)     for i := 0; i < n; i++ {         i := i         go func() {             defer wg.Done()             results[i] = square(i)         }()     }     wg.Wait()     fmt.Println(results)  }  func square(i int) int {     return i * i } 
10

Answers 2: of Is it thread safe to concurrently read/access an array in go?

Yes, reads are thread-safe in Go and virtually all other languages. You're just looking up an address in memory and seeing what is there. If nothing is attempting to modify that go error memory, then you can have as many concurrent reads as you'd like.