Назад к вопросам
Middle
145
questionbank
Что такое starvation (голодание) в контексте многопоточности?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Состояние, когда один или несколько горутин (потоков, процессов) никогда не получают доступ к ресурсу (например, мьютексу, каналу), который им необходим для продолжения выполнения, в то время как другие горутины постоянно получают доступ к этому ресурсу. Это происходит из-за несправедливого планирования или неэффективных механизмов синхронизации, таких как приоритеты или чрезмерное удержание блокировок.
Пример:
package main
import (
"fmt"
"sync"
"time"
)
var (
mu sync.Mutex
counter int
)
func worker(id int) {
for {
mu.Lock() // Защищаем ресурс (counter)
// Здесь может возникнуть голодание, если другие горутины
// постоянно будут захватывать мьютекс и удерживать его долго.
counter++
fmt.Printf("Работник %d увеличил счетчик до %d\n", id, counter)
time.Sleep(10 * time.Millisecond) // Имитация работы
mu.Unlock()
// Добавим небольшую задержку, чтобы планировщик мог переключиться
time.Sleep(1 * time.Millisecond)
}
}
func main() {
for i := 0; i < 5; i++ {
go worker(i)
}
// Программа будет выполняться неограниченно долго,
// но некоторые worker-ы могут испытывать голодание
// в зависимости от планировщика и нагрузки.
select {}
}
Для минимизации starvation применяются:
- Справедливые блокировки (fair locks): Гарантируют, что потоки получают доступ к ресурсу в порядке запроса.
- Randomness: Введение случайности в выбор потока, который получит доступ к ресурсу.
- Timeouts: Установка ограничений по времени на ожидание ресурса.
- Priority inversion avoidance: Избегание ситуаций, когда высокоприоритетный процесс ждет низкоприоритетный.
В Go стандартные мьютексы не гарантируют справедливости, что может привести к starvation при определенных условиях.