Goroutine Temelleri
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 59 / 107.
goroutine, Go çalışma zamanı 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 yalnızca birkaç kilobaytlık yığın alanıyla 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ının önüne go anahtar sözcüğünü yerleştirmeniz yeterlidir:
func sayHello(name string) {
fmt.Println("Hello,", name)
}
func main() {
go sayHello("Alice") // eşzamanlı çalışır
go sayHello("Bob") // eşzamanlı çalışır
time.Sleep(100 * time.Millisecond)
fmt.Println("Done")
}go sayHello("Alice") çalıştığında, sayHello işlevinin tamamlanmasını beklemez. Bunun yerine, sayHello arka planda çalışırken hemen sonraki satıra devam eder. Bu nedenle time.Sleep kullanmamız gerekir; aksi takdirde main, goroutine'ler tamamlanmadan önce çıkar.
Ayrıca goroutine'leri anonim işlevlerle de başlatabilirsiniz:
go func(msg string) {
fmt.Println(msg)
}("Hello from goroutine")Ana işlevin kendisi bir goroutine içinde çalışır. Geri döndüğünde diğer tüm goroutine'ler hemen sonlandırılır. Tamamlanma fırsatı bulamazlar. time.Sleep kullanmak geçici bir çözümdür; sonraki derslerde kanallar ve bekleme gruplarıyla doğru senkronizasyon tekniklerini öğreneceksin.
Görev
KolayGoroutine'leri kullanarak birden çok görevi eşzamanlı yürüten bir görev çalıştırıcısı oluşturalım. Ana program devam ederken görevlerin arka planda çalıştığı basit bir sistem oluşturacak ve goroutine'lerin eşzamanlı yürütmeyi nasıl mümkün kıldığını göstereceksin.
Kodunu iki dosya arasında düzenleyeceksin:
tasks.go: Görev yürütme mantığını tanımla.Task(string) veName(milisaniyeleri temsil eden int) alanlarına sahip birDurationstruct'ı oluştur.Run()üzerinde, görevin süresi kadar uyuyarak çalışmayı simüle eden ve ardındanTaskyazdıran birTask [Name] completedmetodu uygula.Her görevin
RunAllTasks(tasks []Task)metodunu bir goroutine olarak başlatanRun()fonksiyonunu oluştur. Tüm goroutine'leri başlattıktan sonra, tamamlanmalarına olanak tanımak için 500 milisaniye uyumalı, ardındanAll tasks launchedyazdırmalıdır.main.go: Görev bilgilerini oku ve eşzamanlı yürütmeyi düzenle.Görev sayısını, ardından her görevin adını ve süresini oku. Görevleri oluştur ve
RunAllTasksfonksiyonuna aktar. Fonksiyon döndükten sonraMain function doneyazdır.
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Görev sayısı (tam sayı)
- Sonraki satırlar: Her görev için iki satır — görev adı, ardından milisaniye cinsinden süresi
Örneğin, şu verildiğinde:
3
Download
100
Process
50
Upload
75Çıktın, görevlerin tamamlandığını (eşzamanlılık nedeniyle sıra değişebilir), ardından tamamlanma mesajlarını göstermelidir:
Task Process completed
Task Upload completed
Task Download completed
All tasks launched
Main function doneNot: Goroutine'ler eşzamanlı çalıştığından, daha kısa süreli görevler genellikle önce tamamlanır. Görevlerin tamamlanma sırası sürelerine bağlıdır — kısa görevler uzun görevlerden önce tamamlanır.
Gecikmeler için time.Sleep ile time.Duration ve time.Millisecond kullan. RunAllTasks içindeki uyku olmadan fonksiyonun, goroutine'ler çalışmalarını tamamlamadan önce döneceğini unutma.
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ştur
// TODO: Her görevin adını ve süresini oku
// Her görev için:
// - Görev adını oku
// - Süreyi oku (integer olarak)
// - Bir Task oluştur ve slice'ına ekle
// TODO: RunAllTasks'ı tasks slice'ın ile çağır
// TODO: Print "Main function done"
}
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
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker PoolKendi başına pratik yap: Online Go derleyicisi