Sobes.tech
Middle

Go dasturida o'zaro bloklanish (deadlock) holatidan qanday qochish mumkin?

sobes.tech AI

AIdan javob

Go'da qarşılıqlı bloklama ən çox mutexlər və kanalların düzgün istifadə edilməməsi nəticəsində yaranır. Bunu aşağıdakı üsullarla qarşısını almaq olar:

  • Mutexlərin ardıcıl alınması: Bir neçə mutex alınarkən, bunu bütün gorutinalarda həmişə eyni ardıcıllıqla edin.
  • Bloklamalar üçün zaman aşımı: Bloklamaları və ya kanallardan məlumat alarkən zaman aşımı ilə kontekstlərdən istifadə edin ki, sonsuz gözləmənin qarşısını alın.
  • Buffersiz kanallar: Anlayın ki, buffersiz kanallar həm göndərən, həm də qəbul edən tərəfin davam etməsini tələb edir. Yanlış istifadə bloklanmaya səbəb ola bilər.
  • Bufferli kanallar: Kanalın buffer ölçüsünü düzgün seçin. Çox kiçik buffer bloklanmaya səbəb ola bilər, əgər göndərənlər və qəbul edənlər sinxronlaşdırılmayıbsa.
  • select istifadə: Bir neçə kanal ilə işləyərkən, select operatorundan default və ya zaman aşımı ilə istifadə edin ki, tək bir kanal üçün gözləməkdən qaçınasınız.
  • Kodu analiz edin: Statik analiz (go vet, staticcheck) və yarış şərtlərini aşkar edən alətlər (go run -race) istifadə edin, bunlar potensial qarşılıqlı bloklamanın yerlərini tapmağa kömək edə bilər.
  • Resursların hierarxiyası: Əgər resurslar hiyerarşiyə malikdirsə, onları yuxarıdan aşağıya doğru alın.
  • Dairəvi asılılıqları qarşısını alın: Gorutina A-nın B tərəfindən tutulan resursu gözləməsi və B-nin A tərəfindən tutulan resursu gözləməsi vəziyyətlərini yaradmayın.

select və zaman aşımı ilə istifadə nümunəsi:

import (
	"context"
	"time"
)

func nümunə(ch chan int) {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()

	select {
	case val := <-ch:
		// Dəyəri emal et
		_ = val
	case <-ctx.Done():
		// Zaman aşımı baş verdi
	}
}