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:
LockyUnlock.Lockbloquea el mutex yUnlocklo 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.Mutexdeclara 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.Mutexdeclara un mutex para sincronizar el acceso al mapa. - Goroutines: Se lanzan varias goroutines para procesar diferentes partes del texto en paralelo.
- WaitGroup:
sync.WaitGroupse 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
