Choosing Between Mutexes and Channels: When to Use Each
Introduction
When synchronizing concurrent access to shared resources in Go, two primary options are available: sync.Mutex and channels (chan). While both can achieve synchronization, their suitability depends on specific scenarios.
Mutex vs. Channel
Mutex (sync.Mutex):
- Locks a resource, allowing only one goroutine to access it at a time.
- Provides exclusive ownership and guarantees that the locked resource remains in a consistent state.
Channel (chan):
- Facilitates communication between goroutines by passing messages or data.
- Supports concurrent access from multiple goroutines, allowing for data exchange and synchronization.
When to Use a Mutex
-
Guarding an internal state: Mutexes are suitable for protecting shared variables within a single goroutine, such as internal structures or caches.
-
Cache problems: Mutexes can synchronize access to cached data, ensuring data consistency and preventing race conditions.
-
For better performance: Mutexes can be more efficient than channels in certain scenarios where exclusive ownership of a resource is essential.
Examples:
- A simple counter using a mutex for synchronized increment and decrement operations.
var count int
var m sync.Mutex
func increment() {
m.Lock()
defer m.Unlock()
count++
}
Copy after login
- A "ping-pong" game using a mutex to pass a shared ball between two goroutines.
var ball *Ball
var m sync.Mutex
func player(name string) {
for {
m.Lock()
ball.hits++
fmt.Println(name, ball.hits)
time.Sleep(100 * time.Millisecond)
m.Unlock()
}
}
Copy after login
- A simple cache using a mutex to synchronize access to a map.
var cache map[string]interface{}
var m sync.Mutex
func get(key string) interface{} {
m.Lock()
defer m.Unlock()
return cache[key]
}
Copy after login
The above is the detailed content of Mutexes vs. Channels in Go: When to Use Each?. For more information, please follow other related articles on the PHP Chinese website!