Middle
Mi az éhség (starvation) a több szálas környezetben?
sobes.tech MI
Válasz az MI-től
Az állapot, amikor egy vagy több goroutine (szál, folyamat) soha nem fér hozzá egy erőforráshoz (például, mutex, csatorna), amelyre szükségük van a folytatáshoz, miközben más goroutine-ok folyamatosan hozzáférnek ehhez az erőforráshoz. Ez igazságtalan ütemezés vagy hatékonytalan szinkronizációs mechanizmusok, például prioritások vagy túlzott zárolás tartása miatt fordul elő.
Példa:
package main
import (
"fmt"
"sync"
"time"
)
var (
mu sync.Mutex
counter int
)
func worker(id int) {
for {
mu.Lock() // Az erőforrás (counter) védelme
// Itt éhínség fordulhat elő, ha más goroutine-ok
// folyamatosan elfoglalják a mutexet és hosszú ideig tartják.
counter++
fmt.Printf("Munkás %d növelte a számlálót %d-re\n", id, counter)
time.Sleep(10 * time.Millisecond) // Munka szimulálása
mu.Unlock()
// Kisebb késleltetés hozzáadása, hogy a ütemező váltson
time.Sleep(1 * time.Millisecond)
}
}
func main() {
for i := 0; i < 5; i++ {
go worker(i)
}
// A program végtelenül fut,
// de néhány munkás éhínséget tapasztalhat
// az ütemező és a terhelés függvényében.
select {}
}
Az éhínség minimalizálására alkalmazzák:
- Méltányos zárolások (fair locks): Biztosítják, hogy a szálak a kérés sorrendjében férjenek hozzá az erőforráshoz.
- Véletlenszerűség: Véletlenszerűség bevezetése a kiválasztásban, hogy melyik szál férjen hozzá az erőforráshoz.
- Időkorlátok (timeouts): Az erőforrás várakozási idejének korlátozása.
- Prioritás-inverzió elkerülése: Olyan helyzetek elkerülése, amikor egy magas prioritású folyamat egy alacsony prioritású várakozik.
A Go-ban az alapértelmezett mutexek nem garantálják az igazságosságot, ami bizonyos körülmények között éhínséghez vezethet.