Sobes.tech
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():
		// Време истекло
	}
}