Sync Paketi: WaitGroup ve Mutex ile Thread Güvenliği

  • Konbuyu başlatan Konbuyu başlatan irfo
  • Başlangıç tarihi Başlangıç tarihi

irfo

Moderatör
Katılım
7 Ocak 2026
Mesajlar
290
Tepkime puanı
2
Puanları
18

Trafik Polisi​

Goroutine'ler harikadır ama kontrolsüzce kullanılırsa "Race Condition" (Yarış Durumu) oluşur. İki goroutine aynı anda aynı değişkene yazmaya çalışırsa veri bozulur veya program patlar (panic).sync paketi, bu kaosu yönetmek için trafik ışıkları ve bariyerler sunar.

1.​

Önceki derslerde goroutine'leri beklemek için time.Sleep kullanmıştık. Bu yanlıştır. Doğrusu WaitGroup kullanmaktır.

Kod:
package main

import ("fmt""sync""time")

func isci(id int, wg *sync.WaitGroup) {defer wg.Done() // 3. İş bitince sayacı düşfmt.Printf("İşçi %d başladı\n", id)time.Sleep(time.Second)fmt.Printf("İşçi %d bitti\n", id)}

func main() {var wg sync.WaitGroup

for i := 1; i &lt;= 3; i++ {<br>&nbsp;&nbsp;&nbsp;&nbsp;wg.Add(1) // 1. Sayacı artır (Yeni işçi geliyor)<br>&nbsp;&nbsp;&nbsp;&nbsp;go isci(i, &amp;wg)<br>}<br><br>fmt.Println("Tüm işçiler bekleniyor...")<br>wg.Wait() // 2. Sayaç 0 olana kadar burada blokla (bekle)<br>fmt.Println("Tüm işler tamamlandı!")<br>
}

2.​

Bir banka hesabı düşünün. Aynı anda iki kişi para yatırırsa ne olur?Mutex (Mutual Exclusion), bir kaynağı kilitler, işi bitince açar.

Kod:
package main

import ("fmt""sync")

type BankaHesabi struct {Bakiye intmu     sync.Mutex // Kilitleme mekanizması}

func (h *BankaHesabi) ParaYatir(miktar int, wg *sync.WaitGroup) {defer wg.Done()

// KİLİTLE: Şu andan itibaren benden başka kimse Bakiye'ye dokunamaz<br>h.mu.Lock()<br><br>// Kritik Bölge (Critical Section)<br>mevcut := h.Bakiye<br>h.Bakiye = mevcut + miktar<br><br>// KİLİDİ AÇ: Sıradaki gelebilir<br>h.mu.Unlock()<br>
}

func main() {hesap := BankaHesabi{Bakiye: 0}var wg sync.WaitGroup

// 1000 tane Goroutine aynı anda hesaba 1 TL yatırıyor<br>for i := 0; i &lt; 1000; i++ {<br>&nbsp;&nbsp;&nbsp;&nbsp;wg.Add(1)<br>&nbsp;&nbsp;&nbsp;&nbsp;go hesap.ParaYatir(1, &amp;wg)<br>}<br><br>wg.Wait()<br>// Mutex olmasaydı sonuç 1000'den küçük çıkardı (Veri kaybı)<br>fmt.Println("Son Bakiye:", hesap.Bakiye)<br>
}

Sonuç​

Eşzamanlı programlamada kural şudur: Eğer bir veriyi birden fazla goroutine değiştirecekse, orayı korumaya almalısın. Ya Channels ile veriyi taşıyın ya da Mutex ile kilitleyin. Go'da go run -race main.go komutu ile kodunuzda yarış durumu olup olmadığını test edebilirsiniz.
 
Geri
Üst