skip to content
Alvin Lucillo

Atomic operations with Go's sync/atomic

/ 1 min read

💻 Tech

Atomic operations are operations that are performed without effects on other operations in another goroutines (or threads). In the sample code below, since counter++ isn’t an atomic operation, the output may vary.

func main() {
	count := 0

	const x = 10
	var wg sync.WaitGroup
	wg.Add(x)
	for i := 0; i < x; i++ {
		go func() {
			defer wg.Done()
			for j := 0; j < 10_000; j++ {
				count++ // non atomic operation
			}

		}()
	}

	wg.Wait()
	fmt.Println(count) // prints different results, not expected 100000 (10 * 10000)
}

To make it atomic, use the sync/atomic package like so:

func main() {
	var count int64

	const x = 10
	var wg sync.WaitGroup
	wg.Add(n)
	for i := 0; i < x; i++ {
		go func() {
			defer wg.Done()
			for j := 0; j < 10_000; j++ {
				atomic.AddInt64(&count, 1)
			}

		}()
	}

	wg.Wait()
	fmt.Println(count) // prints 100000
}