Sobes.tech
Middle

Go программасында өзара блоктонуудан (deadlock) кантип качып өту керек?

sobes.tech AI

AIден жооп

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
	}
}