GUI (Grafiksel Kullanıcı Arayüzü)

Kanallar (Channels)

Kanallar, Go dilinde asenkron programlama yaparken değer aktarımı yapabileceğimiz hatlardır. Kanala değer atanması iş parçacığı tarafından bekleneceği için asenkron işlemler arasındaki senkronizasyonu ayarlayabiliriz. Kanallar make() fonksiyonu ile oluşturulur.

Örnek
k := make(chan bool)

Yukarıdaki örnekte make() fonksiyonu ile k isminde bir kanal oluşturduk. Bu kanalın özelliği bool tipinde değer taşımasıdır. Yani bu kanal ile true veya false değerlerini taşıyabiliriz. Kanala değer göndermek için <- işaretini kullanırız. Yani bir nevi atama işlemi yapıyoruz. Atama işleminden farkı, kanala atama işlemi yapılana kadar iş parçacığının devam etmemesidir.

Örnek Atama
k <- true

Atama işlemi ile kanalımıza değer yolladık. Bir de bu kanalın çıkış noktası olması gerekir. Bu çıkış noktasında, ister kanaldan gelen veriyi bir değişkene atayabiliriz, istersek de sadece kanala veri gelmesini bekleyebiliriz.

Kanaldan gelen değeri değişkene atama
a := <-k

Yukarıdaki örnekte a isimli değişkene k kanalından gelen bool tipinde değer atadık. a değişkenine atama işlemi k kanalına değer gönderildiği zaman yapılacaktır. Yani k kanalına değer gelene kadar iş parçacığı duraklatılacaktır. (Program k kanalına gelecek değeri bekler.)

Sadece kanala değer gelmesini beklemek
<- k

Yukarıdaki anlatılanlardan yola çıkarak bir örnek oluşturalım.

Örnek kanal işlemleri
package main
import (
"time"
)
func main() {
//bir kanal oluşturalım
k := make(chan bool)
//bu kanalımız bool değer taşıyacak
//asenkron bir iş parçacığı oluşturalım
go func() {
//bu iş parçacığı 5 sn beklesin
time.Sleep(time.Second * 5)
//k kanalına bool bir değer gönderelim
k <- true
}()
//ana iş parçacığı k kanalına değer gelene kadar bekleyecek
<-k
//değer geldiğinde program sonlanacaktır.
}

Boyutlu Kanal Oluşturma

Oluşturduğumuz kanala boyut vermek de mümkün. Yani kanalımıza birden fazla değer yollayabiliyoruz. Bunun için kanalı oluştururken make() fonksiyonunda boyutu da belirtelim.

Örnek
package main
import (
"fmt"
"time"
)
func main() {
//2 adet bool değer taşıyan bir kanal oluşturalım
k := make(chan bool, 2)
//asenkron bir iş parçacığı oluşturalım
go func() {
//5 sn beklesin
time.Sleep(time.Second * 5)
//k kanalına bool bir değer gönderelim
k <- true
//tekrardan 2 sn beklesin
time.Sleep(time.Second * 2)
//ve k kanalına 2. değer de gönderilsin.
k <- false
}()
//ana iş parçacığı k kanalına 2 değer gelene kadar bekleyecek
fmt.Println(<-k, <-k) //çıktı: true false
//iki bool değeri de baştırmak için k kanalını 2 defa yazdık
}

Ana iş parçacığı (main() içerisine yazılan kodlar) devam etmek için k kanalına gelen 2 değeri de bekleyecektir.

fmt.Println() içerisine sadece bir defa <-k yazsaydık, k kanalına ilk gelen değeri ekrana bastıracaktı.