En este módulo, aprenderemos sobre los mutexes y cómo se utilizan para sincronizar el acceso a recursos compartidos en programas concurrentes en Go. La concurrencia es una característica poderosa de Go, pero también puede llevar a problemas como condiciones de carrera si no se maneja correctamente. Los mutexes son una herramienta esencial para evitar estos problemas.
Conceptos Clave
- Mutex: Abreviatura de "mutual exclusion" (exclusión mutua), es un mecanismo que permite que solo una goroutine acceda a un recurso compartido a la vez.
- Condiciones de Carrera: Ocurren cuando dos o más goroutines acceden a un recurso compartido al mismo tiempo y al menos una de las accesos es una escritura.
- Bloqueo y Desbloqueo: Los mutexes tienen dos operaciones principales:
Lock
yUnlock
.Lock
bloquea el mutex yUnlock
lo desbloquea.
Ejemplo Práctico
Vamos a ver un ejemplo práctico de cómo usar un mutex en Go.
Código sin Mutex (Condición de Carrera)
package main import ( "fmt" "time" ) var counter int func increment() { for i := 0; i < 1000; i++ { counter++ } } func main() { go increment() go increment() time.Sleep(time.Second) fmt.Println("Counter:", counter) }
En este ejemplo, dos goroutines están incrementando la variable counter
al mismo tiempo. Esto puede llevar a una condición de carrera, y el valor final de counter
puede no ser el esperado.
Código con Mutex
package main import ( "fmt" "sync" "time" ) var counter int var mutex sync.Mutex func increment() { for i := 0; i < 1000; i++ { mutex.Lock() counter++ mutex.Unlock() } } func main() { go increment() go increment() time.Sleep(time.Second) fmt.Println("Counter:", counter) }
En este ejemplo, hemos añadido un mutex para proteger el acceso a la variable counter
. Ahora, solo una goroutine puede incrementar counter
a la vez, evitando condiciones de carrera.
Explicación del Código
- Declaración del Mutex:
var mutex sync.Mutex
declara un mutex. - Bloqueo y Desbloqueo:
mutex.Lock()
bloquea el mutex antes de incrementarcounter
, ymutex.Unlock()
lo desbloquea después de la operación.
Ejercicio Práctico
Ejercicio 1: Sincronización de Acceso a un Mapa
Crea un programa que use un mapa para contar la frecuencia de palabras en un texto. Usa goroutines para procesar diferentes partes del texto en paralelo y un mutex para sincronizar el acceso al mapa.
Solución
package main import ( "fmt" "strings" "sync" ) var wordCount = make(map[string]int) var mutex sync.Mutex func countWords(text string, wg *sync.WaitGroup) { defer wg.Done() words := strings.Fields(text) for _, word := range words { mutex.Lock() wordCount[word]++ mutex.Unlock() } } func main() { var wg sync.WaitGroup texts := []string{ "hello world", "world of Go", "hello concurrency", } for _, text := range texts { wg.Add(1) go countWords(text, &wg) } wg.Wait() fmt.Println("Word Count:", wordCount) }
Explicación del Ejercicio
- Mapa Compartido:
var wordCount = make(map[string]int)
declara un mapa para contar las palabras. - Mutex:
var mutex sync.Mutex
declara un mutex para sincronizar el acceso al mapa. - Goroutines: Se lanzan varias goroutines para procesar diferentes partes del texto en paralelo.
- WaitGroup:
sync.WaitGroup
se usa para esperar a que todas las goroutines terminen.
Resumen
En esta sección, hemos aprendido sobre los mutexes y cómo se utilizan para sincronizar el acceso a recursos compartidos en programas concurrentes en Go. Hemos visto ejemplos prácticos y ejercicios para reforzar los conceptos. Los mutexes son una herramienta esencial para evitar condiciones de carrera y asegurar que los programas concurrentes funcionen correctamente.
En el próximo módulo, exploraremos más sobre la concurrencia en Go, incluyendo el uso de canales y la instrucción select
.
Curso de Programación en Go
Módulo 1: Introducción a Go
- Introducción a Go
- Configuración del Entorno de Go
- Tu Primer Programa en Go
- Sintaxis y Estructura Básica
Módulo 2: Conceptos Básicos
Módulo 3: Estructuras de Datos Avanzadas
Módulo 4: Manejo de Errores
Módulo 5: Concurrencia
Módulo 6: Temas Avanzados
Módulo 7: Desarrollo Web con Go
Módulo 8: Trabajando con Bases de Datos
Módulo 9: Despliegue y Mantenimiento
- Construcción y Despliegue de Aplicaciones Go
- Registro de Logs
- Monitoreo y Optimización de Rendimiento
- Mejores Prácticas de Seguridad