Skip to content

Latest commit

 

History

History
105 lines (71 loc) · 2.6 KB

File metadata and controls

105 lines (71 loc) · 2.6 KB

Understanding Go's sync/atomic Package

The sync/atomic package in Go provides low-level atomic memory primitives useful for implementing synchronisation algorithms.

drawing

Table of Contents

  1. Introduction to Atomic Operations
  2. Atomic Variables
  3. Atomic Functions
  4. Use Cases
  5. Common Pitfalls
  6. Best Practices
  7. Resources

Introduction

Atomic operations provide a way to read or modify values in memory in a way that ensures that no other operations can occur concurrently that would see a partially completed state or interfere with the operation.

Atomic Variables

import "sync/atomic"

counter := atomic.Int64{}

Atomic Functions

Add

// Increment counter atomically
value := atomic.AddInt64(&counter, 1)

Load and Store

// Atomically load the value of counter
value := atomic.LoadInt64(&counter)

// Atomically store a value in counter
atomic.StoreInt64(&counter, 42)

Compare and Swap

// Atomically compare counter to old and if they are equal set counter to new
swapped := atomic.CompareAndSwapInt64(&counter, old, new)

Examples and tests

See package

Use Cases

Atomic operations are used when you need to ensure that operations on memory are completed without interruption, such as when implementing counters, flags, and other synchronisation primitives.

Common Pitfalls

  • Mixing atomic operations with regular, non-atomic operations on the same variable can lead to data races and unpredictable behavior.
var counter int64 // shared variable

// Incorrect Usage: Mixing atomic and non-atomic operations
func incrementNonAtomic() {
    counter++
}

func incrementAtomic() {
    atomic.AddInt64(&counter, 1)
}

Best Practices

  • Avoid mixing atomic and non-atomic operations on the same variable.
  • Utilize the specialized types in the sync/atomic package over general integer types for atomic operations to ensure type safety, platform independence, and clearer, less error-prone code.
var counterInt int
var counterInt64 atomic.Int64

// Avoid increment using int variable
atomic.AddInt64((*int64)(&counterInt), 1)

// Instead increment using atomic.Int64 variable
counterInt64.Add(1)

Resources