CodeBlanks Logo Icon CodeBlanks

sync.Mutex

Mutex ile paylaşılan veriye erişimi senkronize etmeyi öğrenirsin.

sync.Mutex

Birden çok goroutine aynı değişkene aynı anda yazarsa veri yarışı (data race) oluşur ve sonuç öngörülemez. sync.Mutex bir kodu aynı anda yalnızca bir goroutine'in çalıştırmasını sağlar:

var mu sync.Mutex
sayac := 0

mu.Lock()
sayac++
mu.Unlock()

Lock ile Unlock arasındaki bölgeye kritik bölge denir.

defer Unlock ve yarış dedektörü

Kilidi açmayı unutmak programı kilitler (deadlock). En güvenli desen kilitten hemen sonra defer yazmaktır:

func (s *Sayac) Artir() {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.n++
}

Yarışları bulmak için go test -race ya da go run -race kullan. Mutex içeren bir struct kopyalanmamalıdır; bu yüzden yöntemler işaretçi alıcı kullanır.

Uygulama Güvenli sayaç

type Sayac struct { mu sync.Mutex; n int } ve kilitli Artir() yöntemini yaz. 100 goroutine'in her biri bir kez Artir çağırsın; sync.WaitGroup ile bekleyip n'yi yazdır.

Başlangıç kodu

main.go
package main

import (
    "fmt"
    "sync"
)

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
package main

import (
    "fmt"
    "sync"
)

type Sayac struct {
    mu sync.Mutex
    n  int
}

func (s *Sayac) Artir() {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.n++
}

func main() {
    var s Sayac
    var wg sync.WaitGroup
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            s.Artir()
        }()
    }
    wg.Wait()
    fmt.Println(s.n)
}

Beklenen çıktı

100

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>sayac++</code> neden kilitsiz güvenli değildir?

  • int türü paylaşılamaz
  • Derleyici izin vermez
  • Oku-artır-yaz üç adımdır; araya başka goroutine girebilir Doğru cevap
  • ++ operatörü yavaştır

Açıklama: İki goroutine aynı eski değeri okuyup birer artırırsa bir artış kaybolur. go run -race bu yarışı yakalar.

2 Kilidi aç

Soru
s.mu.Lock()
____ s.mu.Unlock()
s.n++
Cevap
s.mu.Lock()
defer s.mu.Unlock()
s.n++

Açıklama: defer Unlock, fonksiyon nasıl biterse bitsin kilidin açılmasını garanti eder.

3 Kavram

Kavram Anlamı
Veri yarışı Eşzamanlı korumasız erişim
Kritik bölge Lock ile Unlock arası
Deadlock Açılmayan kilit
-race Yarış dedektörü

Orta seviye bölümündeki tüm dersler