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.
selectistifadə: Bir neçə kanal ilə işləyərkən,selectoperatorundandefaultvə 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
}
}