Sobes.tech
Middle

Mutex nedir, hangi tür mutexler vardır ve nasıl kullanılırlar?

sobes.tech yapay zeka

AI'dan gelen yanıt

Mutex (İngilizce MUTual EXclusion ifadesinden gelir) bir senkronizasyon primitive'idir ve yarışan goroutine'lar arasında paylaşılan bir kaynağa münhasır erişimi sağlamak için kullanılır. Herhangi bir zamanda sadece bir goroutine'in mutex'e sahip olmasını ve korunan verilere erişmesini garanti eder.

Go'da, sync paketi iki ana mutex türü sağlar:

  • sync.Mutex: Standart mutex. Lock() ve Unlock() metodlarını sağlar. Eğer mutex zaten kilitliyse, Lock() çağrısı geçerli goroutine'i, serbest bırakılana kadar engeller. Unlock() mutex'i serbest bırakır.

    var mu sync.Mutex
    var counter int
    
    func increment() {
        mu.Lock() // counter'a erişimi kilitler
        counter++
        mu.Unlock() // erişimi serbest bırakır
    }
    
  • sync.RWMutex: Okuma/yazma mutex'i. Aynı anda birden fazla goroutine'un korunan kaynağı okumalarına izin verir, ancak sadece bir goroutine yazabilir. Lock(), Unlock() (yazma için), RLock() ve RUnlock() (okuma için) metodlarını sağlar.

    var rwMu sync.RWMutex
    var data []int
    
    func readData() {
        rwMu.RLock() // Okuma için kilitler
        // data'yı oku
        fmt.Println(data)
        rwMu.RUnlock() // Okumayı serbest bırakır
    }
    
    func writeData(val int) {
        rwMu.Lock() // Yazma için kilitler
        // data'ya yaz
        data = append(data, val)
        rwMu.Unlock() // Yazmayı serbest bırakır
    }
    

Mutex'lerin kullanımı, yarış durumu (race conditions) önlemek için gereklidir; birden fazla goroutine aynı anda aynı verileri değiştirmeye çalıştığında, bu öngörülemeyen sonuçlara yol açar.

Kullanım kuralları:

  1. Korunan kaynağa erişmeden önce Lock() çağrısı yapın.
  2. Erişimi tamamladıktan sonra Unlock() çağrısı yapın. Panik durumunda bile serbest bırakmayı garanti etmek için defer mu.Unlock() kullanılması önerilir.
  3. Aynı goroutine'dan zaten kilitli olan mutex'i kilitlemeye çalışmayın (bu deadlock'a yol açabilir).
  4. Kilitli olmayan mutex'i serbest bırakmaya çalışmayın.
  5. RWMutex kullanırken, okuma işlemleri için RLock/RUnlock, yazma işlemleri için Lock/Unlock kullanın.
  6. Mutex'ler ilk kullanımdan sonra kopyalanmamalıdır. Referans veya gösterici ile iletin.

defer kullanımı örneği:

func safeIncrement() {
    mu.Lock()
    defer mu.Unlock() // Serbest bırakmayı garanti eder
    counter++
}