Kanallar ile Go Eşzamanlılığında Ustalaşın
Bir keresinde Go ile bir görüntü işleme hattı (pipeline) kurmuştum.
Her adım için goroutine'ler kullandım. Onları kanallarla birbirine bağladım. Çalıştırdım.
Program dondu. Bellek kullanımı tırmandı. Sonra çöktü. Hiçbir hata yoktu. Sadece sessizlik vardı.
Bozuk bir zamanlayıcıyı (scheduler) hata ayıklamak için saatlerimi harcadım. Yanılmışım. Kanalların nasıl çalıştığını anlamamıştım.
Go programlarınızın asılı kalmasını önlemek için işte üç kural.
- Nil kanallar kara deliktir Nil bir kanal sonsuza kadar bloklar. Nil bir kanala veri gönderirseniz veya ondan veri alırsanız, goroutine takılı kalır.
- Kanallarınızı her zaman
makeile başlatın. - Emin değilseniz bir nil kontrolü yapın.
- Kapatma kuralları panikleri önler Bir kanalı kapatmak kalıcıdır.
- Kanalı yalnızca gönderen kapatmalıdır.
- Kapatılmış bir kanala veri göndermek panik (panic) neden olur.
- Bir kanalın kapalı olup olmadığını kontrol etmek için ikinci dönüş değerini kullanın:
v, ok := <-ch. - Eğer
okfalse ise kanal kapatılmıştır.
- Güvenlik için kanal yönlerini kullanın Go, bir kanalın gönderme mi yoksa alma amaçlı mı olduğunu belirtmenize olanak tanır.
chan<- intsadece veri gönderebileceğiniz anlamına gelir.<-chan intsadece veri alabileceğiniz anlamına gelir.- Bu, derleyicinin kodunuzu çalıştırmadan önce hataları yakalamasını sağlar.
Temiz bir pipeline nasıl oluşturulur:
- Bir kanalın tam olarak bir kez kapatılmasını sağlamak için
defer closekullanın. - Kanallar üzerinde döngü kurmak için
rangekullanın. Bu, kanal kapandığında otomatik olarak durur. - Katı sözleşmeler oluşturmak için fonksiyonlarınıza yön tipleri (direction types) atayın.
Bu desenleri takip ettiğinizde, sızıntıları (leaks) ve panikleri önlersiniz. Test edilmesi kolay ve sağlam sistemler inşa edersiniz.
Sizin meydan okumanız:
Birden fazla giriş kanalını tek bir çıkış kanalında birleştiren bir fonksiyon yazın. Bir select döngüsü kullanın. 500ms'lik bir zaman aşımı (timeout) ekleyin. Hiçbir goroutine sızıntısı (leak) olmadığından emin olun.
Çözümünüzü yorumlarda paylaşın.