Sobes.tech
Middle

Qu'est-ce que la famine (starvation) dans le contexte de la programmation multithread?

sobes.tech IA

Réponse de l'IA

État dans lequel un ou plusieurs goroutines (fils, processus) n'accèdent jamais à une ressource (par exemple, un mutex, un canal) dont ils ont besoin pour continuer leur exécution, tandis que d'autres goroutines y accèdent constamment. Cela se produit en raison d'une planification injuste ou de mécanismes de synchronisation inefficaces, tels que les priorités ou la rétention excessive de verrouillages.

Exemple:

package main

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

var (
	mu      sync.Mutex
	counter int
)

func worker(id int) {
	for {
		mu.Lock() // Protection de la ressource (counter)
		// Ici, une famine peut survenir si d'autres goroutines
		// capturent constamment le mutex et le maintiennent longtemps.
		counter++
		fmt.Printf("Travailleur %d a augmenté le compteur à %d\n", id, counter)
		time.Sleep(10 * time.Millisecond) // Simulation de travail
		mu.Unlock()
		// Ajout d'une petite pause pour permettre au planificateur de changer de contexte
		time.Sleep(1 * time.Millisecond)
	}
}

func main() {
	for i := 0; i < 5; i++ {
		go worker(i)
	}

	// Le programme s'exécutera indéfiniment,
	// mais certains workers peuvent subir une famine
	// en fonction du planificateur et de la charge.
	select {}
}

Pour minimiser la famine, on applique:

  • Verrous équitables (fair locks): Garantissent que les threads accèdent à la ressource dans l'ordre de la demande.
  • Aléa: Introduire de l'aléa dans la sélection du thread qui accédera à la ressource.
  • Timeouts: Fixer des limites de temps pour attendre une ressource.
  • Éviter l'inversion de priorité: Éviter les situations où un processus de haute priorité attend un processus de basse priorité.

Dans Go, les mutex standards ne garantissent pas l'équité, ce qui peut conduire à la famine dans certaines conditions.