Sobes.tech
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()-u mu.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.Mutex strukturu 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.RWMutex istifadə edərək oxuma/yazma: Əgər əməliyyatların çoxu oxumaqdır və yazma nadirdirsə, sync.RWMutex daha 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: -race bayrağı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]
}