Menu
Coddy logo textTech

Riepilogo: worker pool

Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 66 di 107.

challenge icon

Sfida

Facile

Costruiamo un sistema di elaborazione delle attività usando il modello del pool di worker! Creerai un pool di worker che elaborano attività computazionali in parallelo, mostrando come canali, goroutine e WaitGroups lavorino insieme per gestire i carichi di lavoro in modo efficiente.

Organizzerai il codice in due file:

  • pool.go: definisci i componenti e la logica del pool di worker.

    Crea una struct Task con i campi ID (int) e Value (int), che rappresentano il lavoro da svolgere.

    Crea una struct Result con i campi TaskID (int) e Computed (int), che rappresentano il lavoro completato.

    Implementa una funzione Worker che accetta un ID worker (int), un canale di attività di sola ricezione (<-chan Task), un canale di risultati di solo invio (chan<- Result) e un puntatore a un sync.WaitGroup. Ogni worker deve:

    • Usare defer wg.Done() per segnalare il completamento
    • Iterare sul canale delle attività per elaborare ogni attività
    • Calcolare, per ogni attività, il quadrato del suo Value
    • Inviare un Result con il TaskID e il quadrato calcolato

    Implementa una funzione RunPool che accetta il numero di worker (int) e una slice di attività. Questa funzione deve:

    • Creare canali con buffer per le attività e i risultati (usa il numero di attività come dimensione del buffer)
    • Avviare il numero specificato di worker come goroutine
    • Inviare tutte le attività al canale delle attività, quindi chiuderlo
    • Usare una goroutine con il WaitGroup per chiudere il canale dei risultati dopo che tutti i worker hanno terminato
    • Raccogliere tutti i risultati in una slice e restituirla

  • main.go: leggi l'input e coordina il pool di worker.

    Leggi il numero di worker, poi il numero di attività. Per ogni attività, leggi il suo ID e il suo valore. Chiama RunPool con i worker e le attività, quindi stampa ogni risultato nel formato: Task [TaskID]: [Computed]

    Stampa i risultati ordinati per TaskID in ordine crescente.

Verranno forniti i seguenti input:

  • Riga 1: numero di worker (intero)
  • Riga 2: numero di attività (intero)
  • Righe successive: per ogni attività, due righe: l'ID dell'attività (intero), poi il suo valore (intero)

Per esempio, dato:

2
4
1
3
2
5
3
2
4
7

L'output dovrebbe essere:

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

I worker elaborano le attività in parallelo (3 al quadrato è 9, 5 al quadrato è 25, ecc.) e i risultati vengono raccolti e visualizzati in ordine di TaskID. Con 2 worker che gestiscono 4 attività, il lavoro viene distribuito in modo efficiente nel pool.

Provalo tu

package main

import (
	"fmt"
	"sort"
)

func main() {
	// Leggi il numero di lavoratori
	var numWorkers int
	fmt.Scanln(&numWorkers)

	// Leggi il numero di attività
	var numTasks int
	fmt.Scanln(&numTasks)

	// Leggi le attività
	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: Chiama RunPool con i lavoratori e le attività

	// TODO: Ordina i risultati per TaskID in ordine crescente

	// TODO: Stampa ogni risultato nel formato: Task [TaskID]: [Computed]
}

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Go online