Özet - Worker Pool
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 66 / 107.
Görev
KolayWorker pool desenini kullanarak bir görev işleme sistemi oluşturalım! İş yüklerini verimli bir şekilde yönetmek için kanalların (channels), goroutine'lerin ve WaitGroup'ların nasıl birlikte çalıştığını gösteren, hesaplama görevlerini eşzamanlı olarak işleyen bir işçi havuzu (worker pool) oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
pool.go: İşçi havuzu bileşenlerinizi ve mantığınızı tanımlayın.Yapılacak işi temsil eden
ID(int) veValue(int) alanlarına sahip birTaskyapısı (struct) oluşturun.Tamamlanan işi temsil eden
TaskID(int) veComputed(int) alanlarına sahip birResultyapısı (struct) oluşturun.Bir işçi kimliği (int), salt-alınır bir görev kanalı (
<-chan Task), sonuçlar için salt-gönderilir bir kanal (chan<- Result) ve birsync.WaitGroupişaretçisi alan birWorkerfonksiyonu uygulayın. Her işçi şunları yapmalıdır:- Tamamlandığını bildirmek için
defer wg.Done()kullanmalıdır - Her bir görevi işlemek için görevler kanalı üzerinde döngü (range) kurmalıdır
- Her görev için, görevin Value alanının karesini hesaplamalıdır
- TaskID ve hesaplanan kareyi içeren bir Result göndermelidir
İşçi sayısını (int) ve bir görev dilimini (slice) alan bir
RunPoolfonksiyonu uygulayın. Bu fonksiyon şunları yapmalıdır:- Görevler ve sonuçlar için tamponlanmış kanallar (buffered channels) oluşturun (tampon boyutu olarak görev sayısını kullanın)
- Belirtilen sayıda işçiyi goroutine olarak başlatın
- Tüm görevleri görevler kanalına gönderin ve ardından kanalı kapatın
- Tüm işçiler bittikten sonra sonuçlar kanalını kapatmak için WaitGroup ile bir goroutine kullanın
- Tüm sonuçları bir dilim (slice) içinde toplayın ve geri döndürün
- Tamamlandığını bildirmek için
main.go: Girişi okuyun ve işçi havuzunu koordine edin.Önce işçi sayısını, ardından görev sayısını okuyun. Her görev için ID'sini ve değerini okuyun. İşçiler ve görevlerle
RunPoolfonksiyonunu çağırın, ardından her sonucu şu formatta yazdırın:Task [TaskID]: [Computed]Sonuçları TaskID'ye göre artan düzende sıralanmış olarak yazdırın.
Aşağıdaki girişler sağlanacaktır:
- Satır 1: İşçi sayısı (tamsayı)
- Satır 2: Görev sayısı (tamsayı)
- Takip eden satırlar: Her görev için iki satır - görev ID'si (tamsayı), ardından değeri (tamsayı)
Örneğin, şu giriş verildiğinde:
2
4
1
3
2
5
3
2
4
7Çıktınız şu şekilde olmalıdır:
Task 1: 9
Task 2: 25
Task 3: 4
Task 4: 49İşçiler görevleri eşzamanlı olarak işler (3'ün karesi 9, 5'in karesi 25, vb.) ve sonuçlar toplanarak görev ID'sine göre sırayla görüntülenir. 4 görevi üstlenen 2 işçi ile iş yükü havuz genelinde verimli bir şekilde dağıtılır.
Kendin dene
package main
import (
"fmt"
"sort"
)
func main() {
// İşçi sayısını oku
var numWorkers int
fmt.Scanln(&numWorkers)
// Görev sayısını oku
var numTasks int
fmt.Scanln(&numTasks)
// Görevleri oku
tasks := make([]Task, numTasks)
for i := 0; i < numTasks; i++ {
var id, value int
fmt.Scanln(&id)
fmt.Scanln(&value)
tasks[i] = Task{ID: id, Value: value}
}
// YAPILACAK: RunPool'u işçiler ve görevlerle çağır
// YAPILACAK: Sonuçları TaskID'ye göre artan sırada sırala
// YAPILACAK: Her sonucu şu formatta yazdır: Task [TaskID]: [Computed]
}
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 Pool