Sobes.tech
Middle+

Farklı goroutine'lere dilimler (slices) geçirmek ne kadar güvenlidir?

sobes.tech yapay zeka

AI'dan gelen yanıt

Farklı goroutine'lara doğrudan slice'lar iletmek güvenli değildir eğer goroutine'lar bunları senkronizasyon olmadan aynı anda değiştirirse veya slice, başka bir goroutine'e iletildikten sonra (başlık kopyasıyla) değiştirilirse.

Güvensizlik nedenleri:

  • Paylaşılan temel dizi: Slice'lar başlıklar (temel diziye işaretçi, uzunluk, kapasite) olup ortak bir temel diziye işaret eder.
  • Yarış durumu (Race Condition): Aynı anda temel dizinin aynı öğesine yazmak veya boyutunu değiştirmek, yarış durumlarına, tahmin edilemeyen sonuçlara ve hatalara yol açar.

Goroutine'lerde slice ile güvenli çalışma yolları:

  1. Kopya slice iletmek: Slice'ın tam bir kopyasını oluşturup iletin. Bu güvenlidir çünkü goroutine'lar ayrı verilerle çalışır.

    // tam bir kopya oluşturma
    newSlice := make([]int, len(originalSlice))
    copy(newSlice, originalSlice)
    
  2. Kanallar kullanmak: Slice öğelerini veya slice'ı doğrudan kanallar aracılığıyla iletin. Kanallar, senkronizasyon ve veri izolasyonu sağlar.

    // öğeleri kanal aracılığıyla iletmek
    ch := make(chan int)
    go func() {
        for _, v := range originalSlice {
            ch <- v
        }
        close(ch)
    }()
    
    // slice'ı kanal aracılığıyla iletmek
    chSlice := make(chan []int)
    go func() {
        chSlice <- originalSlice // başlık değeriyle iletim, ancak kanal senkronize eder
                                // önemli: gönderim sonrası originalSlice'ı değiştirmeyin
    }()
    
  3. sync.Mutex veya sync.RWMutex ile senkronizasyon: Slice erişimini mutex'lerle koruyun. Bu, sadece bir goroutine'in slice'ı herhangi bir zamanda değiştirmesini sağlar.

    import "sync"
    
    var mu sync.Mutex
    var sharedSlice []int
    
    func modifySlice(index, value int) {
        mu.Lock()
        defer mu.Unlock()
        if index < len(sharedSlice) {
            sharedSlice[index] = value
        }
    }
    

Yaklaşımların karşılaştırması:

Yaklaşım Güvenlik Büyük slice'lar ile performans Karmaşıklık
Slice kopyası Yüksek Daha düşük (veri kopyası) Basit
Kanallar Yüksek Bağlı (kanal işlemlerinin maliyeti) Orta
Mutex'ler Yüksek Yüksek (ağır çatışmalar yoksa) Orta

Sonuç olarak, slice başlığını ek bir senkronizasyon veya kopya olmadan farklı goroutine'lara iletmek güvenli değildir. Veri güvenliğini sağlamak için yukarıdaki yöntemlerden birini kullanmak gerekir.