Sobes.tech
Middle

¿Qué tipos de mutex proporciona la biblioteca estándar de Go?

sobes.tech AI

Respuesta de la IA

La biblioteca estándar de Go proporciona dos tipos principales de mutex en el paquete sync:

  • sync.Mutex: Mutex básico que garantiza exclusión mutua. Puede estar en dos estados: bloqueado o desbloqueado. Solo una goroutine puede mantener el bloqueo en un momento dado.
  • sync.RWMutex: Mutex para lectura/escritura. Permite que múltiples goroutines lean datos simultáneamente (obteniendo RLock), pero solo una escriba datos (obteniendo Lock). La escritura bloquea todas las operaciones (tanto lectura como escritura).

Métodos principales de sync.Mutex:

Método Descripción
Lock() Bloquea el mutex. Si ya está bloqueado, la goroutine que lo llama se bloquea hasta que se libere.
Unlock() Desbloquea el mutex. Genera un pánico si no estaba bloqueado por la goroutine que lo llama.

Métodos principales de sync.RWMutex:

Método Descripción
Lock() Bloquea el mutex para escritura. Bloquea todas las operaciones de lectura y escritura.
Unlock() Desbloquea el mutex para escritura. Genera un pánico si no estaba bloqueado para escritura.
RLock() Bloquea el mutex para lectura. No bloquea otras operaciones de lectura. Se bloquea si hay bloqueo de escritura.
RUnlock() Desbloquea el mutex para lectura. Genera un pánico si no estaba bloqueado para lectura.
RLocker() Devuelve un Locker que usa RLock y RUnlock.

Ejemplo de uso de sync.Mutex:

package main

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

var counter int
var mutex sync.Mutex

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

func main() {
	for i := 0; i < 10; i++ {
		go increment()
	}
	time.Sleep(time.Second) // Da tiempo a que las goroutines terminen
}

Ejemplo de uso de sync.RWMutex:

package main

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

var data string
var rwMutex sync.RWMutex

func readData() {
	rwMutex.RLock() // Bloquea para lectura
	fmt.Printf("Leyendo datos: %s\n", data)
	rwMutex.RUnlock() // Desbloquea para lectura
}

func writeData(newData string) {
	rwMutex.Lock() // Bloquea para escritura
	data = newData
	fmt.Printf("Escribiendo datos: %s\n", data)
	rwMutex.Unlock() // Desbloquea para escritura
}

func main() {
	go writeData("Hola")
	time.Sleep(100 * time.Millisecond) // Da tiempo a la escritura

	for i := 0; i < 5; i++ {
		go readData() // Se permiten múltiples lecturas simultáneas
	}

	time.Sleep(time.Second) // Da tiempo a que las goroutines terminen
	go writeData("Mundo")
	time.Sleep(100 * time.Millisecond)
	go readData()

	time.Sleep(time.Second)
}