🤔 Расскажи, что такое starvation/голодание?



Это состояние, при котором одна или несколько горутин (или потоков) не получают достаточного доступа к необходимым ресурсам для выполнения своих задач. Это может произойти по нескольким причинам, таким как неправильное управление блокировками или приоритетами, что приводит к несправедливому распределению ресурсов.



🚩Основные причины голодания



🟠Приоритеты

Если потоки с более низким приоритетом постоянно вытесняются потоками с более высоким приоритетом, они могут вообще не получить доступ к ресурсу.

🟠Блокировки

При использовании мьютексов или других механизмов синхронизации, если один поток постоянно захватывает мьютекс, другие потоки могут не получить возможности захватить его и выполнить свою работу.

🟠Бесконечное ожидание

Потоки могут попасть в состояние бесконечного ожидания, если они не могут получить доступ к ресурсу из-за постоянной занятости другими потоками.



🚩Пример голодания



Один поток постоянно захватывает мьютекс, не давая другим потокам шанса выполнить свою работу. В этом примере функция greedyWorker постоянно захватывает мьютекс, блокируя доступ к sharedResource для других горутин (функций starvedWorker). Это приводит к тому, что starvedWorker не получает шанса выполнить свою работу.

package main



import (

"fmt"

"sync"

"time"

)



var mu sync.Mutex

var sharedResource int



func greedyWorker() {

for {

mu.Lock()

sharedResource++

fmt.Println("Greedy worker incremented sharedResource to:", sharedResource)

mu.Unlock()

time.Sleep(100 * time.Millisecond) // Короткая задержка для демонстрации

}

}



func starvedWorker(id int, wg *sync.WaitGroup) {

defer wg.Done()

mu.Lock()

fmt.Printf("Starved worker %d is running\n", id)

sharedResource++

mu.Unlock()

}



func main() {

var wg sync.WaitGroup

wg.Add(5)



go greedyWorker()



for i := 1; i <= 5; i++ {

go starvedWorker(i, &wg)

}



wg.Wait()

fmt.Println("Final sharedResource value:", sharedResource)

}




🚩Способы предотвращения голодания



🟠Справедливые блокировки

Используйте справедливые алгоритмы блокировки, которые предоставляют доступ к ресурсу в порядке очереди.

🟠Управление приоритетами

Обеспечьте сбалансированное управление приоритетами потоков, чтобы потоки с низким приоритетом также получали доступ к ресурсам.

🟠Использование других механизмов синхронизации

Например, вместо использования мьютексов, можно использовать каналы в Go для координации работы между горутинами.

🟠Разделение времени доступа:

Ограничьте время, в течение которого поток может удерживать мьютекс, чтобы другие потоки также могли получить доступ.



Ставь 👍 и забирай 📚 Базу знаний