package main
import (
"fmt"
"math/rand"
"runtime"
"sync"
"time"
)
// Task represents a generic task to be executed
type Task func() Result
// Result represents the result of processing a task
type Result struct {
filename string
duration time.Duration
}
// generateImage creates a random image
func generateImage(filename string, width, height int) Task {
return func() Result {
// We'll just fake this...
delay := time.Duration(rand.Intn(750)+250) * time.Millisecond
time.Sleep(delay)
return Result{filename, delay}
}
}
// processImage applies a simple filter to the image
func processImage(filename string) Task {
return func() Result {
// We'll just fake this...
delay := time.Duration(rand.Intn(750)+250) * time.Millisecond
time.Sleep(delay)
return Result{filename, delay}
}
}
func worker(id int, tasks <-chan Task, results chan<- Result, wg *sync.WaitGroup) {
defer wg.Done()
for task := range tasks {
fmt.Printf("Worker %d processing new task...\n", id)
results <- task()
}
}
const MAX_WORKERS = 4
func executeTasks(tasks []Task) time.Duration {
numWorkers := runtime.NumCPU()
if numWorkers > MAX_WORKERS {
numWorkers = MAX_WORKERS
}
tasksChan := make(chan Task, len(tasks))
resultsChan := make(chan Result, len(tasks))
// Fill task channel
for _, task := range tasks {
tasksChan <- task
}
close(tasksChan)
// Start worker pool
var wg sync.WaitGroup
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go worker(i, tasksChan, resultsChan, &wg)
}
// Wait for all workers to finish
go func() {
wg.Wait()
close(resultsChan)
}()
// Collect results
var totalDuration time.Duration
for result := range resultsChan {
fmt.Printf("Processed %s in %v\n", result.filename, result.duration)
totalDuration += result.duration
}
return totalDuration
}
func main() {
numImages := 20
var generateTasks []Task
var processTasks []Task
// Create image generation tasks
for i := 0; i < numImages; i++ {
filename := fmt.Sprintf("image_%d.png", i)
generateTasks = append(generateTasks, generateImage(filename, 1000, 1000))
}
// Execute image generation tasks
fmt.Println("Generating images...")
genDuration := executeTasks(generateTasks)
fmt.Printf("All images generated in %v\n", genDuration)
fmt.Printf("Average time per image generation: %v\n", genDuration/time.Duration(numImages))
// Create image processing tasks
for i := 0; i < numImages; i++ {
filename := fmt.Sprintf("image_%d.png", i)
processTasks = append(processTasks, processImage(filename))
}
// Execute image processing tasks
fmt.Println("\nProcessing images...")
procDuration := executeTasks(processTasks)
fmt.Printf("All images processed in %v\n", procDuration)
fmt.Printf("Average time per image processing: %v\n", procDuration/time.Duration(numImages))
fmt.Printf("\nTotal time: %v\n", genDuration+procDuration)
}