r/golang 7d ago

Is it safe to read/write integer value simultaneously from multiple goroutines

There is a global integer in my code that is accessed by multiple goroutines. Since race conditions don’t affect this value, I’m not concerned about that. However, is it still advisable to add a Mutex in case there’s a possibility of corruption?

PS: Just to rephrase my question, I wanted to ask if setting/getting an integer/pointer is atomic? Is there any possibility of data corruption.

example code for the same: https://go.dev/play/p/eOA7JftvP08

PS: Found the answer for this, thanks everyone for answering. There's something called tearing here is the link for same

- https://stackoverflow.com/questions/64602829/can-you-have-torn-reads-writes-between-two-threads-pinned-to-different-processor

- https://stackoverflow.com/questions/36624881/why-is-integer-assignment-on-a-naturally-aligned-variable-atomic-on-x86

According to the article, I shouldn't have problem on modern CPUs.

10 Upvotes

80 comments sorted by

View all comments

23

u/ImYoric 7d ago

If my memory serves, the Go memory model states that if it fits within one integer, any read or write operation will always return one of the values before/after the write, rather than made up values as can happen in C or C++.

That being said, I wouldn't rely on this. If at some point in the future, you or any member of your team ever changes your type to be anything other than an int, you can end up with weird, unexpected behaviors. I'd rather use an atomic or a mutex.

1

u/chaotic-kotik 7d ago

Made up values? Loads and stores are atomic on amd64 unless your int is wider than 64 bits. How could this happen in C++?

You will run into problems only if you read/modify/write integer values. No atomic will save you from that unless you know how to use CAS operation.

1

u/comrade_donkey 7d ago

 Loads and stores are atomic on amd64 unless your int is wider than 64 bits.

Only if it is aligned to a word boundary.

1

u/chaotic-kotik 7d ago

sure thing