In Go, mutexes and synchronization mechanisms are used to safely coordinate access to shared resources in concurrent programs. Let's explore mutexes and synchronization in detail, along with examples.
Mutexes in Go:
A mutex (short for mutual exclusion) is a synchronization primitive that prevents multiple goroutines from accessing a shared resource simultaneously. It ensures that only one goroutine can access the critical section (protected code) at a time.
Creating a Mutex:
To create a mutex, use the 'sync'package's 'Mutex'type.
var mu sync.Mutex
Locking and Unlocking Mutex:
A goroutine can lock a mutex using the 'Lock()' method to enter a critical section and unlock it using the 'Unlock()'method to exit the critical section.
mu.Lock() // Lock the mutex // Critical section: shared resource access mu.Unlock() // Unlock the mutex
Example of Mutex:
var (
balance int
mu sync.Mutex
)
func deposit(amount int) {
mu.Lock()
defer mu.Unlock()
balance += amount
}
func withdraw(amount int) {
mu.Lock()
defer mu.Unlock()
if balance >= amount {
balance -= amount
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
deposit(100)
}()
go func() {
defer wg.Done()
withdraw(50)
}()
wg.Wait()
fmt.Println("Final balance:", balance)
}
In this example, the 'Mutex' ensures that only one goroutine can access the 'balance' variable at a time, preventing data race conditions.
RWMutex:
'sync.RWMutex'(read-write mutex) allows multiple readers or a single writer at a time. Multiple goroutines can read concurrently, but only one can write.
Example of RWMutex:
var ( data map[string]string dataMutex sync.RWMutex )
func writeData(key, value string) { dataMutex.Lock() defer dataMutex.Unlock() data[key] = value }
In this example, multiple goroutines can read 'data'concurrently using the 'RLock()'method, while a single goroutine can write using the 'Lock()' method.
Atomic Operations:
The 'sync/atomic' package provides atomic operations for basic types like integers and pointers. These operations are often more efficient than using mutexes when dealing with simple operations.
Summary:
Mutexes are synchronization primitives used to protect shared resources.
Mutexes are created using the 'sync.Mutex' type.
Lock a mutex using'Lock()' and unlock using 'Unlock()' to enter/exit a critical section.
RWMutex allows multiple readers or a single writer.
Use 'sync/atomic'for atomic operations on basic types.
Understanding mutexes and synchronization mechanisms is crucial for building safe and efficient concurrent programs. By using mutexes, you can prevent data races and ensure proper coordination between goroutines accessing shared resources.