Home  >  Article  >  Backend Development  >  Concurrency patterns in Go; worker pools and fan-out/fan-in

Concurrency patterns in Go; worker pools and fan-out/fan-in

DDD
DDDOriginal
2024-10-07 22:11:01500browse

Concurrency patterns in Go; worker pools and fan-out/fan-in

Go is known for its exceptional concurrency model, but many developers focus only on goroutines and channels. However, concurrency patterns like worker pools and fan-out/fan-in provide real efficiency.

This article will get into these advanced concepts, helping you maximize throughput in your Go applications.

Why Concurrency Matters

Concurrency allows programs to perform tasks efficiently, especially when dealing with tasks like I/O operations, web requests, or background processing. In Go, goroutines provide a lightweight way to manage thousands of concurrent tasks, but without structure, you can run into bottlenecks. That’s where worker pools and fan-out/fan-in patterns come in.

Worker Pools

Worker pools allow you to limit the number of goroutines by assigning tasks to fixed "workers." This prevents oversubscription, reduces resource consumption, and makes task execution manageable.


package main

import (
    "fmt"
    "sync"
    "time"
)

func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for j := range jobs {
        fmt.Printf("Worker %d started job %d\n", id, j)
        time.Sleep(time.Second) // Simulate work
        fmt.Printf("Worker %d finished job %d\n", id, j)
        results <- j * 2
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)
    var wg sync.WaitGroup

    // Start 3 workers
    for w := 1; w <= 3; w++ {
        wg.Add(1)
        go worker(w, jobs, results, &wg)
    }

    // Send jobs
    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs)

    // Wait for workers to finish
    wg.Wait()
    close(results)

    for result := range results {
        fmt.Println("Result:", result)
    }
}


In this example:

  • We have three workers that process jobs concurrently.
  • Each job is passed to the workers via channels, and results are gathered for processing.

Fan-Out/Fan-In Pattern

The fan-out/fan-in pattern allows multiple goroutines to process the same task, while fan-in gathers the results back into a single output. This is useful for dividing tasks and then aggregating results.


package main

import (
    "fmt"
    "sync"
    "time"
)

func workerFanOut(id int, tasks <-chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for task := range tasks {
        fmt.Printf("Worker %d processing task %d\n", id, task)
        time.Sleep(time.Second) // Simulate work
    }
}

func main() {
    var wg sync.WaitGroup
    tasks := make(chan int, 10)

    // Fan-out: Launch multiple workers
    for i := 1; i <= 3; i++ {
        wg.Add(1)
        go workerFanOut(i, tasks, &wg)
    }

    // Send tasks
    for i := 1; i <= 9; i++ {
        tasks <- i
    }
    close(tasks)

    // Wait for workers to finish
    wg.Wait()

    fmt.Println("All tasks are processed.")
}


In the code above:

  • Fan-Out: We create multiple goroutines (workers) that handle tasks concurrently.
  • Fan-In: After processing, all workers’ results can be aggregated for further processing.

Concurrency patterns can be applied to optimize web servers, batch processing systems, or I/O-bound applications. Using patterns like worker pools and fan-out/fan-in ensures optimal resource usage without overwhelming system capacity.

Next Steps to increase your knowledge:

  • Explore how these patterns can be extended to other concurrency challenges.
  • Build out a real-time web service with a worker pool managing requests.

The key to success in Go’s concurrency is structure. Mastering these concurrency patterns will level up your Go skills and help you write highly performant applications.

Stay tuned for more insights into Go in the next post!

You can support me by buying me a book :)

The above is the detailed content of Concurrency patterns in Go; worker pools and fan-out/fan-in. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Adding API Rate Limiting to Your Go APINext article:None