Sobes.tech
Middle

What types of mutexes does the Go standard library provide?

sobes.tech AI

Answer from AI

The Go standard library provides two main types of mutexes in the sync package:

  • sync.Mutex: A basic mutex that provides mutual exclusion locking. It can be in two states: locked or unlocked. Only one goroutine can hold the lock at any given time.
  • sync.RWMutex: A read/write mutex. It allows multiple goroutines to read data simultaneously (using RLock), but only one goroutine to write data (using Lock). Writing locks all operations (both read and write).

Main methods of sync.Mutex:

Method Description
Lock() Locks the mutex. If the mutex is already locked, the calling goroutine blocks until it is released.
Unlock() Unlocks the mutex. Panics if the mutex was not locked by the calling goroutine.

Main methods of sync.RWMutex:

Method Description
Lock() Locks the mutex for writing. Blocks all read and write operations.
Unlock() Unlocks the mutex for writing. Panics if the mutex was not locked for writing.
RLock() Locks the mutex for reading. Does not block other read operations. Blocks if there is a write lock.
RUnlock() Unlocks the mutex for reading. Panics if the mutex was not locked for reading.
RLocker() Returns a Locker that uses RLock and RUnlock.

Example of using sync.Mutex:

package main

import (
	"fmt"
	"sync"
	"time"
)

var counter int
var mutex sync.Mutex

func increment() {
	mutex.Lock() // Lock the mutex
	counter++
	fmt.Printf("Counter: %d\n", counter)
	mutex.Unlock() // Unlock the mutex
}

func main() {
	for i := 0; i < 10; i++ {
		go increment()
	}
	time.Sleep(time.Second) // Wait for goroutines to finish
}

Example of using sync.RWMutex:

package main

import (
	"fmt"
	"sync"
	"time"
)

var data string
var rwMutex sync.RWMutex

func readData() {
	rwMutex.RLock() // Lock for reading
	fmt.Printf("Reading data: %s\n", data)
	rwMutex.RUnlock() // Unlock after reading
}

func writeData(newData string) {
	rwMutex.Lock() // Lock for writing
	data = newData
	fmt.Printf("Writing data: %s\n", data)
	rwMutex.Unlock() // Unlock after writing
}

func main() {
	go writeData("Hello")
	time.Sleep(100 * time.Millisecond) // Wait for writing

	for i := 0; i < 5; i++ {
		go readData() // Multiple concurrent reads are allowed
	}

	time.Sleep(time.Second) // Wait for goroutines to finish
	go writeData("World")
	time.Sleep(100 * time.Millisecond)
	go readData()

	time.Sleep(time.Second)
}