Are increment operators in Go atomic on x86?

Here's some background: I need a counter variable shared between go routines, used for something like a leaky-bucket. I know there's an example of leaky-bucket in Effective Go, concurrent section, but the number that I need to track may be very large, and I feel it's inefficient to use number of elements in a channel to track it. So I am considering of using a shared variable between different routines to track the number.

I understand that without explicit configuration, all go routines are mapped onto one thread. But if I assign more than one thread to the program on a multi-core computer, is increment operators atomic? Is it all the same for different data types (int32, float32, etc.) on different machines (x86_32, x86_64, arm)?

To be more concrete, What if I have counter += 1000 in one routine, and counter -= 512 in another routine, and the two routines happens to be running in two threads? Do I need to worry about thread-safty? Shall I put on locks on the counter?

Answers


No, increment should never be assumed to be atomic. Use the atomic addition functions or a mutex.

Lets assume:

import "sync/atomic"
var counter = new(int32)

One goroutine could do atomic.AddInt32(counter, 1000) while another did atomic.AddInt32(counter, -512) without a mutex.

If you would rather use a mutex:

import "sync"
var counter int32
var mutex sync.Mutex

func Add(x int32) {
    mutex.Lock()
    defer mutex.Unlock()
    counter += x
}

Need Your Help

How to get bounds of a google static map?

google-maps map latitude-longitude bounds

How to get bounds in degrees of google static map which has been returned, for example, for following request

Bitbucket git push ssh "conq: invalid repository syntax."

git ssh bitbucket

I cannot git push to my Bitbucket for some reasons. It used to work but it do not work anymore and I can't figure why.