Understanding Locks and Mutex Implementation in Go
This article explains the concept of locks, why they are needed in concurrent programming, and provides an in‑depth look at Go's synchronization primitives—including CAS, atomic operations, spinlocks, semaphores, and the evolution of the sync.Mutex implementation with code examples and performance considerations.
What Is a Lock
A lock is a resource maintained by the operating system for synchronization; a mutex is a mutually exclusive resource that only one thread can hold at a time.
Why Use Locks
Locks ensure data consistency and safety in concurrent programming.
Locks in Go
Go provides synchronization mechanisms in the sync package, such as Mutex , WaitGroup , and channels, built on low‑level primitives like CAS, atomic operations, spinlocks, and semaphores.
1. CAS and Atomic Operations
CAS (Compare And Swap) and atomic operations are the foundation of other synchronization mechanisms.
Atomic operation: an indivisible operation that cannot be interrupted.
CAS: a non‑blocking atomic operation that may need to retry in high‑contention scenarios.
2. Spinlock
A spinlock repeatedly checks the lock state while actively waiting, avoiding thread sleep; Go uses spinlocks internally to implement other lock types.
3. Semaphore
Semaphores implement sleep and wake‑up for goroutines using P (acquire) and V (release) operations.
P(S): allocate a resource, decrement the count, and block if the count becomes negative. V(S): release a resource, increment the count, and wake a blocked goroutine if needed.
Mutex Usage Example
package main
import (
"fmt"
"sync"
)
var num int
var mtx sync.Mutex
var wg sync.WaitGroup
func add() {
mtx.Lock() // mutex does not need explicit instantiation
defer mtx.Unlock()
defer wg.Done()
num += 1
}
func main() {
// Launch 100 goroutines, each incrementing the same counter.
// Without the lock, the final value may not be 100.
for i := 0; i < 100; i++ {
wg.Add(1)
go add()
}
wg.Wait()
fmt.Println("num:", num)
}Why Mutexes Are Necessary
Locks suspend and resume threads under high contention, whereas atomic operations keep the CPU busy; atomic ops are thread‑level only and do not support goroutines, so mutexes are preferred for many concurrent scenarios.
Evolution of Mutex
The modern sync.Mutex is more complex than early versions. Initially, a contended lock caused the goroutine to sleep; later versions introduced spin‑waiting and a starvation‑free mode to improve latency.
1. Basic Mutex Structure
type Mutex struct {
state int32
sema uint32
}
const (
mutexLocked = 1 << iota
mutexWoken
mutexWaiterShift // number of waiters = state >> mutexWaiterShift
)The state field encodes lock status, wake‑up flag, and waiter count using bit masks.
Lock Algorithm
No contention: acquire lock via CAS.
Contention: call runtime_Semacquire to put the goroutine to sleep.
func (m *Mutex) Lock() {
// Fast path: try CAS to set locked state.
if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {
return
}
awoke := false
for {
old := m.state
new := old | mutexLocked
if old&mutexLocked != 0 {
new = old + 1<Unlock Algorithm
Release the lock via CAS.
Wake a sleeping goroutine, decreasing the waiter count.
func (m *Mutex) Unlock() {
if raceenabled {
raceRelease(unsafe.Pointer(m))
}
new := atomic.AddInt32(&m.state, -mutexLocked)
if (new+mutexLocked)&mutexLocked == 0 {
panic("sync: unlock of unlocked mutex")
}
for {
if new>>mutexWaiterShift == 0 || new&(mutexLocked|mutexWoken) != 0 {
return // no waiter or lock already handed off
}
// Wake one waiter.
new = (new - 1<Fair (Starvation‑Free) Mutex
Go's mutex has two modes: normal and starvation. If a goroutine waits longer than 1 ms, the mutex switches to starvation mode, handing the lock directly to the first waiter, reducing long‑tail latency.
References
《go sync.Mutex 设计思想与演化过程 (一)博客园-暮夏》
《GO: sync.Mutex 的实现与演进 简书-董泽润》
《golang之sync.Mutex互斥锁源码分析 简书-freelang》
《Golang同步机制的实现 go语言中文网-无心之祸》
《Golang 并发编程与同步原语 segmentfault-draveness》
《锁的本质 csdn-DIY-GEEKER》
Xueersi Online School Tech Team
The Xueersi Online School Tech Team, dedicated to innovating and promoting internet education technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.