Sobes.tech
Middle

Çox iş parçacığı kontekstində aclıq (starvation) nədir?

sobes.tech Süni İntellekt

AI-dan cavab

Bir və ya bir neçə goroutine (ip, proses) heç vaxt ehtiyacı olan resursa (məsələn, mutex, kanal) daxil olmur, digər goroutine-lər isə bu resursa daim daxil olur. Bu, ədalətsiz planlaşdırma və ya səmərəsiz sinxronizasiya mexanizmləri, məsələn, prioritetlər və ya çox uzun müddət blokların saxlanması səbəbindən baş verir.

Nümunə:

package main

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

var (
	mu      sync.Mutex
	counter int
)

func worker(id int) {
	for {
		mu.Lock() // Resursu (counter) qoruyuruq
		// Burada aclıq baş verə bilər, əgər digər goroutine-lər
		// daim mutex-i ələ keçirib uzun müddət saxlayarsa.
		counter++
		fmt.Printf("İşçi %d sayğacı %d-ə artırdı\n", id, counter)
		time.Sleep(10 * time.Millisecond) // İşin simulyasiyası
		mu.Unlock()
		// Planlayıcının keçid edə bilməsi üçün kiçik gecikmə əlavə edirik
		time.Sleep(1 * time.Millisecond)
	}
}

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

	// Proqram sonsuz davam edəcək,
	// amma bəzi işçilər aclıq çəkə bilər
	// planlayıcı və yükə görə.
	select {}
}

Aclığı azaltmaq üçün tətbiq olunur:

  • Ədalətli kilidlər (fair locks): İstək sırasına görə resursa giriş təmin edir.
  • Təsadüfi seçim: Resursa giriş üçün işçinin seçilməsində təsadüfi elementin daxil edilməsi.
  • Timeoutlar: Resurs üçün gözləmə vaxtını məhdudlaşdırmaq.
  • Prioritet inversiyasını qarşısını alma: Yüksək prioritetli prosesin aşağı prioritetli proses gözləməsini qarşısını alma.

Go-da standart mutexlər ədaləti təmin etmir, bu da bəzi hallarda aclığa səbəb ola bilər.