Menu
Coddy logo textTech

Özet - Worker Pool

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

challenge icon

Görev

Kolay

Worker 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) ve Value (int) alanlarına sahip bir Task yapısı (struct) oluşturun.

    Tamamlanan işi temsil eden TaskID (int) ve Computed (int) alanlarına sahip bir Result yapı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 bir sync.WaitGroup işaretçisi alan bir Worker fonksiyonu 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 RunPool fonksiyonu 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

  • 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 RunPool fonksiyonunu ç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