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