Fundamentals 6 min read

Mastering Go Synchronization Primitives: Mutex, RWMutex, Cond, Semaphore & WaitGroup

This article explains the purpose, types, best practices, and common use cases of synchronization primitives—including mutexes, condition variables, semaphores, and wait groups—in Go, and provides concrete code examples to illustrate safe concurrent programming.

Ops Development & AI Practice
Ops Development & AI Practice
Ops Development & AI Practice
Mastering Go Synchronization Primitives: Mutex, RWMutex, Cond, Semaphore & WaitGroup

Synchronization primitives are mechanisms that control the execution order of processes or threads, ensuring consistent access to shared resources and preventing data races.

Two main categories of synchronization primitives

Mutex (Mutual Exclusion Lock) : protects shared resources by allowing only one thread to access them at a time; it has locked and unlocked states.

Condition Variable (Cond) : used under a mutex to wait for a specific condition; threads wait with Wait and are awakened with Signal or Broadcast.

When using these primitives, keep in mind:

Avoid over‑synchronization : excessive locking hurts performance; use primitives only when necessary.

Use them correctly : improper use can cause deadlocks.

Prefer higher‑level mechanisms : many languages, including Go, offer channels or other abstractions that are often safer than low‑level primitives.

Typical scenarios for synchronization primitives include:

Protecting shared resources : ensure only one thread modifies a resource at a time.

Coordinating thread execution order : enforce a specific sequence of operations across threads.

Improving performance : e.g., using a mutex to avoid contention and increase cache‑hit rates.

Go provides the following synchronization primitives:

Mutex : standard mutual‑exclusion lock for goroutines.

RWMutex : allows multiple readers or a single writer, improving read‑heavy concurrency.

Cond : condition variable that works with a mutex to wait for conditions.

Semaphore : controls access count to a resource via Acquire and Release.

WaitGroup : waits for a collection of goroutines to finish using a counter.

Usage examples

// Mutex protecting a shared counter
var m sync.Mutex
var count int

func increment() {
    m.Lock()
    count++
    m.Unlock()
}

func decrement() {
    m.Lock()
    count--
    m.Unlock()
}

// Condition variable waiting for a flag
var c sync.Cond
var flag bool

func wait() {
    c.L.Lock()
    for !flag {
        c.Wait()
    }
    c.L.Unlock()
}

func signal() {
    c.L.Lock()
    flag = true
    c.Signal()
    c.L.Unlock()
}

// Semaphore controlling access
var s sync.Semaphore

func acquire() {
    s.Acquire()
    // use shared resource
    s.Release()
}

// WaitGroup waiting for goroutines
var wg sync.WaitGroup

func worker() {
    // perform task
    wg.Done()
}

func main() {
    wg.Add(10)
    for i := 0; i < 10; i++ {
        go worker()
    }
    wg.Wait()
}

When applying Go's synchronization primitives, remember to avoid over‑synchronization, use them correctly to prevent deadlocks, and prefer higher‑level constructs like channels whenever they meet the requirements.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Gocondition variable
Ops Development & AI Practice
Written by

Ops Development & AI Practice

DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.