# Most idiomatic way of writing and reading an array at the same time

## Issue

I have one array that gets modified a few times per second with one goroutine. In another function, I read a random value from the array once every few seconds. What would be the most Go-like way of approaching this problem?

In Java, for example, I would lock the array first and then read from it. I’m not sure if I could use channels for this because I don’t want to wait until my other function reads before I can continue updating the array.

``````package main

import (
"fmt"
"math/rand"
"time"
)

const (
SliceLength = 32
)

var mySlice []int

func randInt(min int, max int) int {
return min + rand.Intn(max-min)
}

func writeSlice() {
for index, _ := range mySlice {
mySlice[index] = rand.Intn(100)
}
}

func main() {
rand.Seed(time.Now().UnixNano())
mySlice = make([]int, SliceLength)

// First time just to populate it.
writeSlice()

// Write to the slice.
go func() {
for {
time.Sleep(time.Duration(randInt(10, 50)) * time.Millisecond)
writeSlice()
}
}()

for {
time.Sleep(time.Duration(randInt(1, 5)) * time.Second)
fmt.Println(mySlice[randInt(0, SliceLength)])
}
}
``````

## Solution

A mutex `sync.RWMutex` can work here. You simply share your slice between two goroutines, locking and releasing before/after each slice operation.

Whilst you’re exploring possibilities, you should also consider what the “shared-nothing” principle would mean. You would want to find a solution that does not use a mutex and in which each goroutine has private data only – shared-nothing.

Suppose you had a third goroutine. Think of it as a server. It holds the slice (or any other contended data structure as required). When your first goroutine wants to make a change, it sends a message on a channel to the server, saying “change x to y”. When your second goroutine wants to read the data, it might simply read a copy of the data off a channel coming from the server.

Inside the server, a select statement will choose between incoming update messages and outgoing read messages – bear in mind that the guards can be on either channel inputs or channel outputs, so this is easy to do.

``````...  declare and initialise the slice
for {
select {
case instruction = <-update:
...  apply the instruction to the slice
case output<- slice:
...  sent the slice to the consumer
}
}
``````

Notice that the server code is itself single-threaded, i.e. there is no shared-memory access to the slice, even though the behaviour overall is concurrent. This is a nice feature of the CSP approach: locally, there is never any need to worry about shared access to data. “Shared-nothing” means what it says.

Furthermore, you can fully reason about the possible states of such a piece of code locally, without needing global knowledge. This is a BIG benefit.