Go - Mutex
To avoid conflicts when multiple goroutines access the same variable, a sync.Mutex
lock can be used to synchronize shared memory access.
go
// The zero value for a `Mutex` is an unlocked mutex.
// A `Mutex` must not be copied after first use.
var mu sync.Mutex
// Acquire a lock, called by the goroutine accessing a shared memory.
// If it is already locked, the call will block until the lock becomes available.
mu.Lock()
// The region between the `Lock` and `Unlock` is used to safely access shared memory.
// This is called a critical section.
i++ // Modify a variable safely without conflicts
// Release the lock, called by the goroutine when finished accessing shared memory.
// If the mutex is not locked, `Unlock` will cause a run-time error.
mu.Unlock()
func modify() {
mu.Lock()
// In a function, the `Unlock` call can be deferred.
defer mu.Unlock()
i++
}
Example:
go
package main
import (
"fmt"
"sync"
)
var count int // Shared variable
var mu sync.Mutex // Mutex to guard the shared variable
func main() {
var wg sync.WaitGroup
// Create 1000 goroutines that each increment the count by 1.
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
mu.Lock() // Acquire the lock
defer mu.Unlock() // Release the lock
defer wg.Done() // Signal that the goroutine is done
count++ // Modify the shared variable
}()
}
// Wait for all the goroutines to finish.
wg.Wait()
fmt.Println(count) // 1000
}