Menu
Coddy logo textTech

Goroutine Temelleri

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 59 / 107.

Bir goroutine, Go çalışma zamanı (runtime) tarafından yönetilen hafif bir yürütme iş parçacığıdır. Önemli miktarda bellek tüketen geleneksel iş parçacıklarının aksine, goroutine'ler sadece birkaç kilobaytlık yığın (stack) alanı ile başlar ve bu da binlercesini eşzamanlı olarak çalıştırmanıza olanak tanır.

Bir goroutine başlatmak için, bir fonksiyon çağrısından önce go anahtar kelimesini yerleştirmeniz yeterlidir:

func sayHello(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    go sayHello("Alice")  // eşzamanlı olarak çalışır
    go sayHello("Bob")    // eşzamanlı olarak çalışır
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

go sayHello("Alice") yürütüldüğünde, sayHello fonksiyonunun bitmesini beklemez. Bunun yerine, sayHello arka planda çalışırken hemen bir sonraki satıra geçer. Bu yüzden time.Sleep fonksiyonuna ihtiyaç duyarız—o olmadan, goroutine'ler tamamlanmadan önce main sonlanır.

Goroutine'leri anonim fonksiyonlarla da başlatabilirsiniz:

go func(msg string) {
    fmt.Println(msg)
}("Hello from goroutine")

main fonksiyonunun kendisi bir goroutine içinde çalışır. Bu fonksiyon sonlandığında, diğer tüm goroutine'ler anında durdurulur; tamamlanma şansı bulamazlar. time.Sleep kullanmak geçici bir çözümdür; gelecek derslerde kanallar (channels) ve bekleme grupları (wait groups) ile doğru senkronizasyon tekniklerini öğreneceksiniz.

challenge icon

Görev

Kolay

Goroutine'leri kullanarak birden fazla görevi eşzamanlı olarak yürüten bir görev çalıştırıcı (task runner) oluşturalım. Görevlerin arka planda çalıştığı ve ana programın devam ettiği basit bir sistem oluşturarak, goroutine'lerin eşzamanlı yürütmeyi nasıl sağladığını göreceksiniz.

Kodunuzu iki dosya halinde düzenleyeceksiniz:

  • tasks.go: Görev yürütme mantığınızı tanımlayın.

    Name (string) ve Duration (int, milisaniye cinsinden) alanlarına sahip bir Task yapısı (struct) oluşturun.

    Task üzerinde, görevin süresi kadar uyuyarak çalışmayı simüle eden ve ardından şunu yazdıran bir Run() metodu uygulayın: Task [Name] completed

    Her bir görevin Run() metodunu bir goroutine olarak başlatan bir RunAllTasks(tasks []Task) fonksiyonu oluşturun. Tüm goroutine'leri başlattıktan sonra, tamamlanmalarına izin vermek için 500 milisaniye uyumalı ve ardından şunu yazdırmalıdır: All tasks launched

  • main.go: Görev bilgilerini okuyun ve eşzamanlı yürütmeyi koordine edin.

    Görev sayısını okuyun, ardından her görevin adını ve süresini okuyun. Görevleri oluşturun ve bunları RunAllTasks fonksiyonuna iletin. Fonksiyon döndükten sonra şunu yazdırın: Main function done

Aşağıdaki girdiler sağlanacaktır:

  • Satır 1: Görev sayısı (tam sayı)
  • Sonraki satırlar: Her görev için iki satır - görev adı ve ardından milisaniye cinsinden süresi

Örneğin, şu girdi verildiğinde:

3
Download
100
Process
50
Upload
75

Çıktınız, tamamlanan görevleri (eşzamanlılık nedeniyle sıra değişebilir) ve ardından tamamlanma mesajlarını göstermelidir:

Task Process completed
Task Upload completed
Task Download completed
All tasks launched
Main function done

Not: Goroutine'ler eşzamanlı çalıştığı için, süresi daha kısa olan görevler genellikle daha önce biter. Görevlerin tamamlanma sırası sürelerine bağlıdır - kısa süreli görevler uzun süreli olanlardan önce tamamlanır.

Gecikmeler için time.Duration ve time.Millisecond ile birlikte time.Sleep kullanın. RunAllTasks içindeki uyutma işlemi olmazsa, fonksiyonun goroutine'ler işlerini bitirmeden döneceğini unutmayın.

Kopya kağıdı

Bir goroutine, Go çalışma zamanı (runtime) tarafından yönetilen hafif bir yürütme iş parçacığıdır (thread). Goroutine'ler sadece birkaç kilobaytlık yığın (stack) alanı ile başlar ve binlercesini eşzamanlı olarak çalıştırmanıza olanak tanır.

Bir goroutine başlatmak için, bir fonksiyon çağrısından önce go anahtar kelimesini yerleştirin:

func sayHello(name string) {
    fmt.Println("Hello,", name)
}

func main() {
    go sayHello("Alice")  // eşzamanlı olarak çalışır
    go sayHello("Bob")    // eşzamanlı olarak çalışır
    
    time.Sleep(100 * time.Millisecond)
    fmt.Println("Done")
}

go sayHello("Alice") yürütüldüğünde, sayHello fonksiyonunun bitmesini beklemez. Bunun yerine, sayHello arka planda çalışırken hemen bir sonraki satıra geçer.

Goroutine'leri anonim fonksiyonlarla başlatabilirsiniz:

go func(msg string) {
    fmt.Println(msg)
}("Hello from goroutine")

main fonksiyonunun kendisi de bir goroutine içinde çalışır. O döndüğünde, diğer tüm goroutine'ler derhal sonlandırılır. main fonksiyonu çıkmadan önce goroutine'lerin tamamlanmasına izin vermek için time.Sleep kullanın.

Kendin dene

package main

import (
	"fmt"
)

func main() {
	// Görev sayısını oku
	var numTasks int
	fmt.Scanln(&numTasks)

	// TODO: Görevleri tutmak için bir slice oluşturun
	
	// TODO: Her bir görevin adını ve süresini okuyun
	// Her görev için:
	//   - Görev adını oku
	//   - Süreyi oku (tam sayı olarak)
	//   - Bir Task oluşturun ve slice'ınıza ekleyin

	// TODO: Görev slice'ınız ile RunAllTasks fonksiyonunu çağırın

	// TODO: "Main function done" yazdırın
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler