Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Settings and accessing a pointer from concurrent goroutines

Tags:

go

I have a map which is used by goroutine A and replaced once in a time in goroutine B. By replacement I mean:

var a map[T]N

// uses the map
func goroutineA() {
    for (...) {
        tempA = a
        ..uses tempA in some way...
    }
}

//refreshes the map
func gorountineB() {
    for (...) {
        time.Sleep(10 * time.Seconds)
        otherTempA = make(map[T]N)
        ...initializes other tempA....
        a = otherTempA 
    }
}

Do you see any problem in this pseudo code? (in terms of concurrecy)

like image 520
Alexander Ponomarev Avatar asked Mar 04 '26 09:03

Alexander Ponomarev


1 Answers

The code isn't safe, since assignments and reads to a pointer value are not guaranteed to be atomic. This can mean that as one goroutine writes the new pointer value, the other may see a mix of bytes from the old and new value, which will cause your program to die in a nasty way. Another thing that may happen is that since there's no synchronisation in your code, the compiler may notice that nothing can change a in goroutineA, and lift the tempA := a statement out of the loop. This will mean that you'll never see new map assignments as the other goroutine updates them.

You can use go test -race to find these sorts of problems automatically.

One solution is to lock all access to the map with a mutex.

You may wish to read the Go Memory Model document, which explains clearly when changes to variables are visible inside goroutines.

like image 193
Paul Hankin Avatar answered Mar 06 '26 00:03

Paul Hankin