Soruya giriş:
Kanallar (chan) — goroutine'ler arasında veri alışverişi ve eşzamanlı süreçlerin senkronizasyonu için anahtar bir araçtır, bu da Go'yu diğer dillerden ayırır. Veri aktarımını güvenli bir şekilde sağlamak için tasarlanmıştır.
Sorun:
Geliştiriciler, kanalların yapısını anlamadan deadlock'lar, beklenmedik bloke olmalar, kanalın kapatılmasıyla ilgili belirsiz hatalar ve veri kaybı (race condition) ile sık sık karşılaşırlar.
Çözüm:
Kanalları nasıl tanımlayacağınızı, kullanacağınızı ve kapatacağınızı net bir şekilde anlamalı ve tamponlu / tamponsuz kanalların ne zaman kullanılacağına karar vermeli, ayrıca hangi tarafın ve ne zaman kanalı kapatması gerektiğini takip etmelisiniz ki "her şey dondu" durumundan kaçının.
Kod örneği:
func producer(ch chan<- int) { // sadece gönderim for i := 0; i < 5; i++ { ch <- i } close(ch) } func consumer(ch <-chan int) { // sadece okuma for v := range ch { fmt.Println(v) } } func main() { ch := make(chan int) go producer(ch) consumer(ch) }
Anahtar özellikler:
Kapalı bir kanala yazma girişimi ne olur?
Panic oluşur. Kanalı okuyucu tarafından kapatmak veya kapatılmasının ardından kanala yazmaya izin vermek sık yapılan bir hatadır.
Kanalın kapatılıp kapatılmadığını güvenli bir şekilde öğrenebilir miyiz?
Hayır, doğrudan bir kontrol yoktur. Kanalın yaşam döngüsünü doğru bir şekilde tasarlamak gerektiği gibi, okuma sırasında ikinci bir parametre kullanarak (v, ok := <-ch), bu kanal kapatıldığında false olur.
Kanal kendi başına thread-safe midir?
Kanal, goroutine'ler arasında veri aktarımı için thread-safe'dir. Ancak, birden fazla goroutine'in aynı kanala yazması durumunda, koordinasyon olmadan bu sorunlara yol açabilir (erken kapanma olasılığı).
Birden fazla üretici ve bir tüketici olan bir projede: her üretici kanalı kapatıyordu, sonuç — ikili kapatma girişiminde runtime'da panic, veriler kayboldu.
Artılar:
Eksiler:
Kanalı kapatmak için yalnızca bir thread kullanıldı ve üreticiler ayrı bir WaitGroup ile tamamlanma bildirimi yaptı. Kanal yalnızca sonuçları iletmek için kullanıldı.
Artılar:
Eksiler: