Middle
¿Qué es el starvation (hambruna) en el contexto de la multitarea?
sobes.tech AI
Respuesta de la IA
Estado en el que uno o más goroutines (hilos, procesos) nunca acceden a un recurso (por ejemplo, un mutex, un canal) que necesitan para continuar su ejecución, mientras que otros goroutines acceden constantemente a ese recurso. Esto ocurre debido a una planificación injusta o mecanismos de sincronización ineficaces, como prioridades o retenciones excesivas de bloqueos.
Ejemplo:
package main
import (
"fmt"
"sync"
"time"
)
var (
mu sync.Mutex
counter int
)
func worker(id int) {
for {
mu.Lock() // Protegemos el recurso (counter)
// Aquí puede ocurrir hambre si otras goroutines
// constantemente capturan el mutex y lo mantienen por mucho tiempo.
counter++
fmt.Printf("Trabajador %d incrementó el contador a %d\n", id, counter)
time.Sleep(10 * time.Millisecond) // Simulación de trabajo
mu.Unlock()
// Añadimos una pequeña pausa para que el planificador pueda cambiar de contexto
time.Sleep(1 * time.Millisecond)
}
}
func main() {
for i := 0; i < 5; i++ {
go worker(i)
}
// El programa se ejecutará indefinidamente,
// pero algunos workers pueden experimentar hambre
// dependiendo del planificador y la carga.
select {}
}
Para minimizar el hambre se aplican:
- Bloqueos justos (fair locks): Garantizan que los hilos acceden a los recursos en orden de solicitud.
- Aleatoriedad: Introducir azar en la selección del hilo que accederá al recurso.
- Timeouts: Establecer límites de tiempo para esperar por un recurso.
- Prevención de inversión de prioridades: Evitar situaciones donde un proceso de alta prioridad espera a uno de baja prioridad.
En Go, los mutexes estándar no garantizan justicia, lo que puede llevar a hambre en ciertas condiciones.