Corporate Training
Request Demo
Click me
Menu
Let's Talk
Request Demo

Tutorials

Mutexes and Sync

19. Mutexes and Sync

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 readData(key string) string {
dataMutex.RLock()
defer dataMutex.RUnlock()
return data[key]
}

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.