select — Go'nun kanallar ile çalışmak için güçlü bir yapısıdır. Birden fazla kanaldan veri girişi veya kapanmasını beklemeyi sağlar. Bir durum hazır olduğunda, ilgili dal çalıştırılır, diğerleri mevcut yinelemede göz ardı edilir.
ch1 := make(chan int) ch2 := make(chan string) go func() { ch1 <- 42 }() go func() { ch2 <- "hello" }() select { case i := <-ch1: fmt.Println("ch1'den alındı:", i) case s := <-ch2: fmt.Println("ch2'den alındı:", s) default: fmt.Println("iletişim yok") }
İncelikler:
Eğer select içinde hiç bir kanal okuyup/yazmak için hazır değilse ve default bloğu yoksa ne olur?
Cevap: Select, bir kanal işlem için hazır olana kadar bloklanır.
Hikaye
Geliştirici, select içinde default bloğu olmadan veri akışını kesme işlevini gerçekleştirdi, birkaç denemeden sonra işlevin "kontrolü bırakacağını" varsayarak. Kanallar boş kaldı ve işlev select'te sonsuza dek bloklandı, bu da mikro hizmetin veri akışının donmasına neden oldu.
Hikaye
Birden fazla kanal ile select kullanıldığında, bazı goroutine'lerde kanalların kapanmada işlenmemesi nedeniyle panik oluştu, bu da bellek sızıntılarına ve çöküşlere yol açtı. Kanalın kapanma durumunu kontrol etme (ok değişkeni ile) ihmal edildi.
Hikaye
Bir projede geliştiriciler, blokajlardan kaçınmak için select içinde default bloğu eklediler. Ancak bu, busy loop'a yol açtı — select bir döngüde çalışıyordu, default hemen tetikleniyordu ve işlemci %100 yükleniyordu, kanallardan olay beklemek yerine.