Sobes.tech
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)
}