1

I want to know exactly what could happen when go maps accessed by multiple goroutins lets assume we have a map[int]*User. can modifying fields of User structure by multiple goroutins cause data corruption ? or just operations like len() are not thread safe what would be different if map was thread safe in Go ?

alizx
  • 1,148
  • 2
  • 15
  • 27

2 Answers2

3

Concurrently modifying the *User could cause corruption regardless of the map. Reading the pointer from the map concurrently is safe, as long as there are no modifications to the map. Modifying the data *User points to makes no changes to the map itself.

Concurrently modifying the map[int]*User itself also risks data corruption.

There are no benign data races, always test your code with the race detector.

JimB
  • 104,193
  • 13
  • 262
  • 255
  • Can I consider it thread safe by using locks just for modifications the map itself ,not the user structs? – alizx Jul 30 '15 at 18:04
  • Yes, as long as there is no *concurrent* modification of the User struct. – JimB Jul 30 '15 at 18:10
0

Simplest example;

go WorkerMethodOne(myMapReference)
go WorkerMethodTwo(myMapReference)

in worker method one I have some code like this (example)

for i := 0; i < len(MyMapReference); i++ {
    if i % 2 == 0 {
       delete(MyMapReference, i)
    }
}

Then when WorkerMethodTwo is iterating that same map and tries to access the item that just got deleted, what happens? While a k, err := map[index] may still be safe, unlike in many languages where you'd throw, it doesn't make sense and is unpredictable. Ultimately worse examples could happen like attempts to concurrently write to the value of some *User. It could cause concurrent modification to the actual value (what's at the pointer), or you could have the pointer pulled our from under you and randomly be working with a value different than what you expected ect. It's really no different than if you made two closures run as goroutines and started modifying a non-atomic int without locking/using a mutex. You don't what's going to happen since there is contention for that memory between two fully decoupled executions.

evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115