Middle
Kako izbeći situaciju međusobnog blokiranja (deadlock) u Go programu?
sobes.tech АИ
Одговор од АИ
Обменна блокада у Go најчешће настаје због неправилне употребе мјутака и канала. Њу можете избегнути следећим методама:
- Редоследно добијање мјутака: Када добијате више мјутака, увек то радите у истом редоследу у свим горутинма.
- Временска ограничења за блокаде: Користите контексте са временским ограничењима приликом чекања на блокаде или пријема из канала, како бисте избегли бесконачно чекање.
- Непуњени канали: Разумите да непуњени канали захтевају и пошиљаоца и примаоца да наставе са извршавањем. Неисправна употреба може довести до блокирања.
- Пуњени канали: Правилно изаберите величину пуњеног канала. Превелики или премали буфер може довести до блокирања ако пошиљаоци и примаоци нису синхронизовани.
- Користите
select: Када радите са више канала, користите операторselectсаdefaultгранама или временским ограничењем, како бисте избегли блокирање на једном каналу. - Анализа кода: Користите статичку анализу (
go vet,staticcheck) и алате за откривање трка (go run -race), који такође могу помоћи у идентификовању потенцијалних места за међусобно блокирање. - Иерархија ресурса: Ако ресурси имају хијерархију, добијајте их од врха према дну.
- Избегавајте цикличне зависности: Не стварајте ситуације у којима горутина A чека ресурс који је заузет од стране B, а B чека ресурс који је заузет од стране A.
Пример коришћења select са временским ограничењем:
import (
"context"
"time"
)
func пример(ch chan int) {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
select {
case val := <-ch:
// Обрада вредности
_ = val
case <-ctx.Done():
// Време истекло
}
}