GoLang ve GoRoutines Kullanımı

GoLangGOlang ile asenkron programlama amacıyla kullanılan goroutines için aşağıdaki örneğin açıklayıcı olabileceğini düşünüyorum.

package goroutines

import (
	"fmt"
	"time"
)

func CiftSayilar() {
	for i := 0; i < 10; i += 2 {
		fmt.Println("Çift Sayı:", i)
		
	}
}

func TekSayilar() {
	for i := 1; i < 10; i += 2 {
		fmt.Println("Tek Sayı:", i)
		
	}
}

Yukarıdaki kodlardan da anlaşılacağı üzere CiftSayilar ve TekSayilar fonksiyonları ile ekrana 0-10 arasındaki tek ve çift sayıları yazdırmak üzere iki farklı fonksiyon tanımladık.

Normal şartlarda senkron kodlama da bu fonksiyonları main.go içinden çağırırken şu şekilde yazmamız yeterli oluyordu.

package main

import (
	"fmt"
	"golesson/goroutines"
	
)

func main() {

	goroutines.CiftSayilar()
	goroutines.TekSayilar()
	fmt.Println("Main Bitiyor mu?")
	
	fmt.Println("Main Bitti")
}

ve bu işlemin ekran çıktısı da şu şekilde olurdu

D:\Projeler\Go>go run main.go
Çift Sayı: 0
Çift Sayı: 2
Çift Sayı: 4
Çift Sayı: 6
Çift Sayı: 8
Tek Sayı: 1
Tek Sayı: 3
Tek Sayı: 5
Tek Sayı: 7
Tek Sayı: 9
Main Bitiyor mu?
Main Bitti

göreceğiniz üzere kodları yazdığımız sırada tek tek işlem görüp ekrana o şekilde sonuç vermiş oldu.

Peki ama bu işlemleri asenkron olarak yaptırmak isteseydik nasıl olurdu ?

o zaman main.go dosyamızı aşağıdaki gibi değiştirmemiz ve kodlarımızın başına “go” ifadesini eklememiz gerekir.

package main

import (
	"fmt"
	"golesson/goroutines"
	"time"
)

func main() {

	go goroutines.CiftSayilar()
	go goroutines.TekSayilar()
	go fmt.Println("Main Bitiyor mu?")
	time.Sleep(time.Second)
	fmt.Println("Main Bitti")
}

burada kodlarımızın arasına time.Sleep koyduk çünkü main.go içeriğinde asenkron işlem yaparken main.go asenkron fonksiyonun bitip bitmediğine bakmaz ve işlemi sonlandırır. Fakat biz programdan 1 saniye beklemesini istediğimiz için program çıktımız şu şekilde olur.

D:\Projeler\Go>go run main.go
Main Bitiyor mu?
Tek Sayı: 1
Tek Sayı: 3
Tek Sayı: 5
Tek Sayı: 7
Tek Sayı: 9
Çift Sayı: 0
Çift Sayı: 2
Çift Sayı: 4
Çift Sayı: 6
Çift Sayı: 8
Main Bitti

Peki ama programımızın asenkron çalıştığını söylediğimiz halde ekran çıktısı neden sıralı geldi?

Hatta fonksiyonumuza CiftSayilar önce TekSayilar sonra yer aldığı halde neden Tek Sayılar önce yazıldı?

O zaman alt fonksiyonlarımızın arasına 1 nanosaniyelik bekleme koysak nasıl olurdu.

func CiftSayilar() {
	for i := 0; i < 10; i += 2 {
		fmt.Println("Çift Sayı:", i)
		time.Sleep(time.Nanosecond)
	}
}

func TekSayilar() {
	for i := 1; i < 10; i += 2 {
		fmt.Println("Tek Sayı:", i)
		time.Sleep(time.Nanosecond)
	}
}

bu işlemden sonra ekran çıktımıza bakarsak

D:\Projeler\Go>go run main.go
Main Bitiyor mu?
Çift Sayı: 0
Tek Sayı: 1
Çift Sayı: 2
Çift Sayı: 4
Tek Sayı: 3
Çift Sayı: 6
Çift Sayı: 8
Tek Sayı: 5
Tek Sayı: 7
Tek Sayı: 9
Main Bitti

Sizin de gördüğünüz üzere asenkron olarak kodlarımız aynı anda çalışıyor ve çıktıları içiçe ekrana getirebiliyor.