In Go, managing concurrent processes involves ensuring that Goroutines can safely access shared resources and coordinating their execution. The sync
package provides essential synchronization primitives such as sync.Mutex
and sync.WaitGroup
to address these needs. This guide explores how to use sync.Mutex
and sync.WaitGroup
for effective concurrency management in Go programs.
sync.Mutex
for Synchronizationsync.Mutex
is a mutual exclusion lock used to synchronize access to shared resources. It ensures that only one Goroutine can access a critical section of code at a time, preventing race conditions and data corruption.
**Lock()**
: Acquires the lock. If the lock is already held by another Goroutine, the calling Goroutine will block until the lock is available.**Unlock()**
: Releases the lock. It should be called when the critical section of code is finished.In this example:
sync.Mutex
is used to synchronize access to the counter
variable.Lock()
and Unlock()
methods ensure that only one Goroutine can increment the counter at a time.sync.Mutex
to protect critical sections of code that access shared resources.Unlock()
is always called after Lock()
, even if an error occurs. Consider using defer
to release the lock safely.sync.WaitGroup
for Coordinating Goroutinessync.WaitGroup
is used to wait for a collection of Goroutines to complete their execution. It helps synchronize the completion of multiple concurrent tasks.
**Add(n int)**
: Increments the WaitGroup counter by n
. Each Goroutine should call Add(1)
before starting.**Done()**
: Decrements the WaitGroup counter by 1, signaling that a Goroutine has completed.**Wait()**
: Blocks until the WaitGroup counter is zero, meaning all Goroutines have finished.In this example:
sync.WaitGroup
is used to wait for two printNumbers
Goroutines to complete.Add(2)
is called to indicate that two Goroutines will be waited on, and Done()
is called by each Goroutine when it finishes.sync.WaitGroup
to coordinate the start and completion of multiple Goroutines.Add()
method is called before starting Goroutines and that the number passed to Add()
matches the number of Goroutines.Feature | sync.Mutex | sync.WaitGroup |
---|---|---|
Purpose | Synchronize access to shared resources | Wait for multiple Goroutines to finish |
Blocking | Blocks on Lock() if already locked | Blocks on Wait() until counter is zero |
Usage | Protect critical sections of code | Coordinate completion of concurrent tasks |
Key Method | Lock() , Unlock() | Add() , Done() , Wait() |
Both sync.Mutex
and sync.WaitGroup
are crucial for managing concurrency in Go:
**sync.Mutex**
: Provides mutual exclusion to protect shared resources, preventing race conditions and ensuring data consistency.**sync.WaitGroup**
: Coordinates the execution of multiple Goroutines, making it easy to wait for their completion and manage concurrent tasks.By using these synchronization primitives effectively, you can write safe and efficient concurrent programs in Go.