Menu
Coddy logo textTech

סיכום - מאגר עובדים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 66 מתוך 107.

challenge icon

אתגר

קל

בואו נבנה מערכת לעיבוד משימות באמצעות תבנית מאגר העובדים! תיצור מאגר עובדים שיעבדו במקביל על משימות חישוביות, ותדגים כיצד ערוצים, 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() כדי לסמן שהעבודה הושלמה
    • לעבור על ערוץ המשימות כדי לעבד כל משימה
    • לחשב את ריבוע הערך של כל משימה
    • לשלוח Result עם ה-TaskID והריבוע שחושב

    ממש פונקציה RunPool שמקבלת את מספר העובדים (int) ופרוסה של משימות. הפונקציה צריכה:

    • ליצור ערוצים עם מאגר עבור המשימות והתוצאות (להשתמש במספר המשימות כגודל המאגר)
    • להפעיל את מספר העובדים שצוין בתור goroutines
    • לשלוח את כל המשימות לערוץ המשימות, ואז לסגור אותו
    • להשתמש ב-goroutine עם ה-WaitGroup כדי לסגור את ערוץ התוצאות לאחר שכל העובדים מסיימים
    • לאסוף את כל התוצאות לפרוסה ולהחזיר אותה

  • 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 וכן הלאה), והתוצאות נאספות ומוצגות לפי סדר מזהי המשימות. כש-2 עובדים מטפלים ב-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]
}

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Go אונליין