Middle
Go-da mutex-lərlə işləyərkən nələri yadda saxlamaq lazımdır?
sobes.tech Süni İntellekt
AI-dan cavab
Go dilində (sync.Mutex) mutexlər ilə işləyərkən aşağıdakıları yadda saxlamaq vacibdir:
- Qapama və azad etmə: Mutex mütləq (
Lock()) paylaşılan verilərə girişdən əvvəl qapadılmalı və (Unlock()) iş bitdikdən sonra azad edilməlidir.defer mu.Unlock()-umu.Lock()-dan dərhal sonra istifadə etmək yaxşı təcrübədir, bu, unutmağı qarşısını alır. - Eksklüziv giriş: Mutex yalnız bir goroutine-ə resursa eyni zamanda giriş imkanı verir.
- "Bloklanmış/Bloklanmamış" vəziyyət: Əgər
Lock()artıq bloklanmış mutex üzərində çağırılırsa, çağıran goroutine başqa biri azad edənə qədər bloklanacaq.Unlock()bloklanmamış mutex üzərində çağırılırsa, bu, icra zamanı panikə səbəb olur. - Mutexləri kopyalamayın:
sync.Mutexstrukturu ilk istifadədən sonra kopyalanmaq üçün nəzərdə tutulmayıb. Mutex-i dəyər kimi ötürmək və ya onu ehtiva edən strukturu kopyalamaq düzgün sinxronizasiyaya və panikaya səbəb ola bilər. - Deadlock (ölüm kilidi): İki və ya daha çox goroutine bir-birinin resurslarını azad etməsini gözləyərkən baş verir. Tipik ssenari: A goroutine R1-i bloklayır və R2-ni gözləyir, B goroutine R2-ni bloklayır və R1-i gözləyir.
- Livelock (canlı kilid): Goroutine-lər davamlı olaraq vəziyyətlərini dəyişdirirlər, digərinin hərəkətlərinə cavab olaraq, lakin faydalı iş görmədən və irəliləmədən. Bu, deadlock-dan daha az rast gəlinir.
- Açlıq (starvation): Bir və ya bir neçə goroutine paylaşılan resursa daxil ola bilməz, çünki digər goroutine-lər onu davamlı bloklayır. Go mutexlərində açlıq təmin edilmir.
sync.RWMutexistifadə edərək oxuma/yazma: Əgər əməliyyatların çoxu oxumaqdır və yazma nadirdirsə,sync.RWMutexdaha səmərəli ola bilər. Bu, bir neçə goroutine-ə eyni zamanda oxumağa imkan verir, lakin yazma zamanı bütün oxuma və yazma əməliyyatlarını bloklayır.- Qısa bloklar: Bloklamaları mümkün qədər qısa saxlayın. Mutex çox uzun müddət bloklanarsa, digər goroutine-lər gözləyəcək və paralelliyi azaldacaq.
- Yarış şərtlərini test etmək:
-racebayrağını istifadə etmək, testləri yığmaq və işlətmək zamanı (go test -race) yarış şərtlərini aşkar etməyə kömək edir, bunlar çox vaxt mutexlərin düzgün istifadə edilməməsindən yaranır.
defer istifadə nümunəsi:
import (
"sync"
)
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
// Inc, açar üçün sayğacı təhlükəsiz şəkildə artırır.
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
// Funksiyadan çıxarkən azad edirik.
defer c.mu.Unlock()
c.v[key]++
}
// Value, açar üçün hazırkı sayğac dəyərini qaytarır.
func (c *SafeCounter) Value(key string) int {
c.mu.Lock()
// Dəyəri əldə etdikdən sonra azad edirik.
defer c.mu.Unlock()
return c.v[key]
}