GO Fundamentals - Channels
Channels Nedir?

Bir goroutine’in ürettiği veriyi başka bir goroutine’e aktarmasını sağlar. GO üzerinde concurrency (eşzamanlılık) faaliyetlerini yürütmekte kullanılan bir yapıdır.
Peki eşzamanlılık nedir? Neden ihtiyacımız var?
Concurrency Nedir?
![]()
Birden fazla işin aynı zaman aralığında yönetilmesi ve koordine edilmesidir. Thread (iş parçacığı) adı verilen yapıların eş zamanlı olarak çalıştırılması faaliyetlerini içerir.
- İşlemler paralel olarak aynı zamanda çalışabilir.
- işlemci tarafından sırasıyla da yürütülüyor olabilir.
Concurrency (eşzamanlılık) kavramı için GO Mottosu olarak şu ifadeye dikkat etmek gerekir:
“Belleği paylaşarak iletişim kurma, iletişim kurarak belleği paylaş.”
Yani birden fazla goroutine’in aynı değişken üzerinde doğrudan işlem yapması yerine, verilerin channel aracılığıyla aktarılması bellek açısından daha verimlidir.
GO üzerinde Concurrency Yönetimi
GO üzerinde Concurrency yapıları sadece channels ya da goroutine yapıları ile yürütülmez. Ayrıca sync paketleri de bu noktada kullanılır.
- goroutines
- channels
- sync paketleri
Örnek olarak bir API İstemi (API Request) sırasında aşağıdaki şekilde bir olay akışı olabilir.
- Bir yandan bir goroutine ile veri okuma işlemi devam edebilir
- Diğer bir yandan da veri işleme işlemleri devam edebilir
Channels Neden Kullanılır?
Birden fazla goroutine içeren bir script yazdığınızı var sayalım. Yani sisteminizde concurrently (eş zamanlı) olarak bu işler nasıl yürütülecek sorusu ortaya çıkar. Burada hafızadaki verilerin yönetimi sırasında doğal yapıya bypass yapılarak, sisteme channels ile mesaj göndererek bizim belirlediğimiz sırayla veri akışı yapılacağını belirtiyoruz.
Diğer kullanım alanları:
- goroutines queries
- shared memory
- mutex management
- snyc problems
Eğer bu yapı olmasaydı ne olurdu? Eğer bu yapı olmasaydı, aynı değişken tekrar tekrar paylaşılır ve goroutine sırasına alınırdı. Böylece birden fazla goroutine aynı değişken üzerinde işlem yapar ve bu da işlem ve zaman kaybına sebep olurdu.
Channels kullanılmadığında goroutine’ler genellikle shared memory üzerinden iletişim kurar. Bu durumda mutex gibi ek senkronizasyon mekanizmalarına ihtiyaç duyulur.
Channel Yazımı
Bir channel oluşturmak için aşağıdaki syntax (sözdizimi) kullanılır.
ch :=make(chan string)
Yukarıda string veri tipinde bir channel oluşturduk. Eğer belirli bir sınır vermek istiyorsak string ifadesinden sonra bir , virgül işareti koyarak, bir limit sayısı belirtmemiz gerekiyor. Bu şekilde elde edeceğimiz ch ifadesi bir buffered channel olur.
Örnek Channels Uygulaması
package main
import (
"fmt"
)
func Worker(ch chan string) {
ch <- "Hello Goroutine!"
}
func main() {
ch := make(chan string)
go Worker(ch)
message := <- ch
fmt.Println(message)
}
Burada yazdığımız kodları kısaca inceleyelim.
func Worker(ch chan string) {
ch <- "Hello Goroutine!"
}
Öncelikle Worker isimli channel yapısında ve string türünde argüman alan bir fonksiyon yazdık. Burada "Hello Goroutine!" ifademizi <- işareti yardımıyla ch isimli bir channel ifadesine atıyoruz.
Burada dikkat ederseniz fonksiyonumuzda bir return ifadesi yok. Çünkü atadığımız değer doğrudan buffer adını verdiğimiz tampon hafıza değerinde tutuluyor. Bu hafıza kısa ve anlık bir hafıza değeridir.
func main() {
ch := make(chan string)
go Worker(ch)
message := <- ch
fmt.Println(message)
}
Şimdi main.go isimli bir fonksiyon üzerindeki yapılan işlemleri inceleyelim.
Channel Oluşturma
h := make(chan string)
Öncelikle ch := make(chan string) ifadesi ile ch isimli bir channel değişkeni oluşturduk. Bu değişkende henüz bir değer yok. Değer daha sonra Worker isimli fonksiyondan gelecek.
goroutine Başlatma
go Worker(ch)
Daha Sonrasında ise go Worker(ch) komutu ile Worker isimli fonksiyonumuzu bir goroutine yapısıyla çağırdık. Boş olan ve daha önceden oluşturduğumu ch isimli channel yapısı argüman olarak veriliyor.
Channel'a veri Gönderme
ch <- "Hello Goroutine!"
Worker isimli fonksiyonun channel içerisinde oluşturduğu "Hello Goroutine!" ifadesini ch isimli string formatında oluşturduğumuz yeni bir channel'a aktarıyoruz. Böylece bu ifade buffer denilen geçici hafızada goroutine ile kullanılmak üzere beklemeye başlıyor.
Channel'dan Veri Alma
message := <-ch
message := <- ch ifadesi ile channel üzerinde gerçekleşen string ifadesi işlemlerini message isimli bir değişkene yazdırıyoruz.
Main goroutine’i channel’daki veriyi alır ve message değişkenine aktarır.
Bu işlem gerçekleştiğinde:
- sender ve receiver senkronize olmuş olur, channel üzerindeki mesaj ilgili goroutine'e iletilir
- channel iletişimi tamamlanır
Veriyi Yazdırma
fmt.Println(message)
fmt.Println(message) yapısı ile channel üzerindeki son değeri go routine ile ekrana bastırıyoruz.
Sonsöz ve Değerlendirme
Bu yazıda GO içerisinde channels konusunu basitçe anlatarak, temellerini açıklamış olduk. İlerleyen yazılarda görüşmek üzere...