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