Middle
Que tipos de mutexes a biblioteca padrão do Go fornece?
sobes.tech IA
Resposta da IA
A biblioteca padrão do Go fornece dois tipos principais de mutex no pacote sync:
sync.Mutex: Mutex básico que garante exclusão mútua. Pode estar em dois estados: bloqueado ou desbloqueado. Apenas uma goroutine pode manter o bloqueio de cada vez.sync.RWMutex: Mutex para leitura/gravação. Permite que múltiplas goroutines leiam dados simultaneamente (obtendo RLock), mas apenas uma pode escrever (obtendo Lock). A escrita bloqueia todas as operações (leitura e escrita).
Métodos principais de sync.Mutex:
| Método | Descrição |
|---|---|
Lock() |
Bloqueia o mutex. Se já estiver bloqueado, a goroutine chamadora fica bloqueada até que seja liberado. |
Unlock() |
Desbloqueia o mutex. Gera um pânico se o mutex não estiver bloqueado pela goroutine chamadora. |
Métodos principais de sync.RWMutex:
| Método | Descrição |
|---|---|
Lock() |
Bloqueia o mutex para escrita. Bloqueia todas as operações de leitura e escrita. |
Unlock() |
Desbloqueia o mutex para escrita. Gera um pânico se o mutex não estiver bloqueado para escrita. |
RLock() |
Bloqueia o mutex para leitura. Não bloqueia outras operações de leitura. É bloqueado se houver bloqueio de escrita. |
RUnlock() |
Desbloqueia o mutex para leitura. Gera um pânico se o mutex não estiver bloqueado para leitura. |
RLocker() |
Retorna um Locker que usa RLock e RUnlock. |
Exemplo de uso de sync.Mutex:
package main
import (
"fmt"
"sync"
"time"
)
var counter int
var mutex sync.Mutex
func increment() {
mutex.Lock() // Bloqueia o mutex
counter++
fmt.Printf("Counter: %d\n", counter)
mutex.Unlock() // Desbloqueia o mutex
}
func main() {
for i := 0; i < 10; i++ {
go increment()
}
time.Sleep(time.Second) // Dá tempo às goroutines terminarem
}
Exemplo de uso de sync.RWMutex:
package main
import (
"fmt"
"sync"
"time"
)
var data string
var rwMutex sync.RWMutex
func readData() {
rwMutex.RLock() // Bloqueia para leitura
fmt.Printf("Lendo dados: %s\n", data)
rwMutex.RUnlock() // Desbloqueia para leitura
}
func writeData(newData string) {
rwMutex.Lock() // Bloqueia para escrita
data = newData
fmt.Printf("Escrevendo dados: %s\n", data)
rwMutex.Unlock() // Desbloqueia para escrita
}
func main() {
go writeData("Olá")
time.Sleep(100 * time.Millisecond) // Dá tempo para a escrita
for i := 0; i < 5; i++ {
go readData() // Múltiplas leituras simultâneas permitidas
}
time.Sleep(time.Second) // Dá tempo às goroutines de terminar
go writeData("Mundo")
time.Sleep(100 * time.Millisecond)
go readData()
time.Sleep(time.Second)
}