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.