go mutex
The Go programming language provides a built-in package called sync
that allows us to implement mutual exclusion using a mutex. A mutex, short for mutual exclusion, is a synchronization primitive that ensures that only one thread or goroutine can access a shared resource at a time. In Go, a mutex is implemented using the sync.Mutex
type.
Step 1: Import the sync
package
To use the mutex in Go, we first need to import the sync
package. This can be done using the import statement:
import "sync"
Step 2: Create a Mutex object
Next, we need to create a mutex object using the sync.Mutex
type. This mutex object will be used to control access to the shared resource. We can create a mutex object by declaring a variable of type sync.Mutex
.
var mutex sync.Mutex
Step 3: Lock the Mutex
Before accessing the shared resource, we need to acquire a lock on the mutex. This can be done by calling the Lock()
method on the mutex object. If the mutex is already locked by another goroutine, the Lock()
method will block until the mutex becomes available.
mutex.Lock()
Step 4: Access the Shared Resource
Once we have acquired the lock on the mutex, we can safely access the shared resource. This is the critical section of code where we perform operations on the shared resource.
// Perform operations on the shared resource
Step 5: Unlock the Mutex
After we have finished accessing the shared resource, we need to release the lock on the mutex to allow other goroutines to access the shared resource. This can be done by calling the Unlock()
method on the mutex object.
mutex.Unlock()
By unlocking the mutex, we signal that we are done with the critical section of code and other goroutines can now acquire the lock and access the shared resource.
This sequence of steps ensures that only one goroutine can access the shared resource at a time, preventing data races and ensuring that the shared resource is accessed safely.
Here is a complete example that demonstrates the usage of a mutex in Go:
package main
import (
"fmt"
"sync"
)
var (
counter int
mutex sync.Mutex
wg sync.WaitGroup
)
func main() {
for i := 0; i < 10; i++ {
wg.Add(1)
go increment()
}
wg.Wait()
fmt.Println("Counter:", counter)
}
func increment() {
defer wg.Done()
mutex.Lock()
counter++
mutex.Unlock()
}
In this example, we have a shared counter
variable that is incremented by multiple goroutines. The increment
function is called concurrently by multiple goroutines, and each goroutine acquires a lock on the mutex before incrementing the counter. By using the mutex, we ensure that the counter is incremented safely without any data races.
I hope this explanation helps! Let me know if you have any further questions.