Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

مراجعة - Worker Pool

جزء من قسم Object Oriented Programming في رحلة GO على Coddy — الدرس 66 من 107.

challenge icon

التحدي

سهل

لنقم ببناء نظام لمعالجة المهام باستخدام نمط تجمع العمال (worker pool pattern)! ستقوم بإنشاء تجمع من العمال الذين يعالجون المهام الحسابية بشكل متزامن، مما يوضح كيفية عمل القنوات (channels)، والـ goroutines، والـ WaitGroups معاً للتعامل مع أعباء العمل بكفاءة.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • pool.go: حدد مكونات ومنطق تجمع العمال الخاص بك.

    قم بإنشاء هيكل Task يحتوي على حقول ID (int) و Value (int) لتمثيل العمل المطلوب إنجازه.

    قم بإنشاء هيكل Result يحتوي على حقول TaskID (int) و Computed (int) لتمثيل العمل المكتمل.

    قم بتنفيذ دالة Worker تستقبل معرف العامل (int)، وقناة لاستقبال المهام فقط (<-chan Task)، وقناة لإرسال النتائج فقط (chan<- Result)، ومؤشر إلى sync.WaitGroup. يجب على كل عامل:

    • استخدام defer wg.Done() للإشارة إلى الانتهاء
    • التكرار (Range) عبر قناة المهام لمعالجة كل مهمة
    • لكل مهمة، حساب مربع قيمة Value الخاصة بالمهمة
    • إرسال Result يحتوي على TaskID والمربع المحسوب

    قم بتنفيذ دالة RunPool تستقبل عدد العمال (int) وشريحة (slice) من المهام. يجب على هذه الدالة:

    • إنشاء قنوات مخزنة (buffered channels) للمهام والنتائج (استخدم عدد المهام كحجم للمخزن المؤقت)
    • بدء تشغيل العدد المحدد من العمال كـ goroutines
    • إرسال جميع المهام إلى قناة المهام، ثم إغلاقها
    • استخدام goroutine مع WaitGroup لإغلاق قناة النتائج بعد انتهاء جميع العمال
    • جمع كافة النتائج في شريحة (slice) وإرجاعها
  • main.go: قراءة المدخلات وتنسيق تجمع العمال.

    اقرأ عدد العمال، ثم عدد المهام. لكل مهمة، اقرأ معرفها وقيمتها. استدعِ RunPool مع العمال والمهام، ثم اطبع كل نتيجة بالتنسيق التالي: Task [TaskID]: [Computed]

    اطبع النتائج مرتبة حسب TaskID بترتيب تصاعدي.

سيتم توفير المدخلات التالية:

  • السطر 1: عدد العمال (عدد صحيح)
  • السطر 2: عدد المهام (عدد صحيح)
  • الأسطر التالية: لكل مهمة، سطران - معرف المهمة (عدد صحيح)، ثم قيمتها (عدد صحيح)

على سبيل المثال، إذا كان المعطى:

2
4
1
3
2
5
3
2
4
7

يجب أن يكون مخرجك:

Task 1: 9
Task 2: 25
Task 3: 4
Task 4: 49

يعالج العمال المهام بشكل متزامن (مربع 3 هو 9، مربع 5 هو 25، إلخ)، ويتم جمع النتائج وعرضها مرتبة حسب معرف المهمة. مع وجود عاملين يتعاملان مع 4 مهام، يتم توزيع العمل عبر التجمع بكفاءة.

جرّب بنفسك

package main

import (
	"fmt"
	"sort"
)

func main() {
	// قراءة عدد العمال
	var numWorkers int
	fmt.Scanln(&numWorkers)

	// قراءة عدد المهام
	var numTasks int
	fmt.Scanln(&numTasks)

	// قراءة المهام
	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}
	}

	// TODO: استدعاء RunPool مع العمال والمهام

	// TODO: فرز النتائج حسب TaskID بترتيب تصاعدي

	// TODO: طباعة كل نتيجة بالتنسيق: Task [TaskID]: [Computed]
}

جميع دروس Object Oriented Programming