← Назад ко всем вопросам

Что такое fan-in и fan-out паттерны в Go и где они применяются

1️⃣ Как кратко ответить

Fan-in и fan-out — это паттерны параллельного программирования в Go. Fan-out позволяет нескольким горутинам обрабатывать данные из одного источника, увеличивая производительность. Fan-in объединяет результаты из нескольких источников в один канал, упрощая обработку данных.

2️⃣ Подробное объяснение темы

Fan-in и fan-out — это концепции, которые помогают управлять параллельными задачами в Go, используя каналы и горутины. Эти паттерны позволяют эффективно распределять и собирать данные, что особенно полезно в системах, требующих высокой производительности и масштабируемости.

Fan-out

Fan-out — это паттерн, при котором одна задача распределяется между несколькими горутинами для параллельной обработки. Это позволяет увеличить производительность, так как несколько горутин могут обрабатывать данные одновременно.

Пример:

package main
​
import (
    "fmt"
    "sync"
)
​
// worker обрабатывает данные из канала jobs и отправляет результат в канал results
func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for job := range jobs {
        fmt.Printf("Worker %d processing job %d\n", id, job)
        results <- job * 2 // Пример обработки: умножение на 2
    }
}
​
func main() {
    const numJobs = 5
    jobs := make(chan int, numJobs)
    results := make(chan int, numJobs)
​
    var wg sync.WaitGroup
​
    // Запуск нескольких горутин для обработки задач
    for w := 1; w <= 3; w++ {
        wg.Add(1)
        go worker(w, jobs, results, &wg)
    }
​
    // Отправка задач в канал jobs
    for j := 1; j <= numJobs; j++ {
        jobs <- j
    }
    close(jobs)
​
    // Ожидание завершения всех горутин
    wg.Wait()
    close(results)
​
    // Чтение и вывод результатов
    for result := range results {
        fmt.Println("Result:", result)
    }
}

Объяснение:

  • worker — функция, которая принимает идентификатор, канал задач и канал результатов. Она обрабатывает каждую задачу, умножая её на 2, и отправляет результат в канал results.
  • main — функция, где создаются каналы jobs и results, а также запускаются три горутины worker.
  • wg — используется для ожидания завершения всех горутин.
  • Задачи отправляются в канал jobs, который закрывается после отправки всех задач.
  • Результаты обрабатываются и выводятся из канала results.

Fan-in

Fan-in — это паттерн, при котором результаты из нескольких источников объединяются в один канал. Это упрощает обработку данных, так как все результаты собираются в одном месте.

Пример:

package main
​
import (
    "fmt"
    "sync"
)
​
// generator создает канал, из которого можно читать данные
func generator(nums ...int) <-chan int {
    out := make(chan int)
    go func() {
        for _, n := range nums {
            out <- n
        }
        close(out)
    }()
    return out
}
​
// fanIn объединяет несколько входных каналов в один выходной
func fanIn(channels ...<-chan int) <-chan int {
    var wg sync.WaitGroup
    out := make(chan int)
​
    // Функция для чтения из входного канала и записи в выходной
    output := func(c <-chan int) {
        defer wg.Done()
        for n := range c {
            out <- n
        }
    }
​
    // Запуск горутин для каждого входного канала
    wg.Add(len(channels))
    for _, c := range channels {
        go output(c)
    }
​
    // Закрытие выходного канала после завершения всех горутин
    go func() {
        wg.Wait()
        close(out)
    }()
​
    return out
}
​
func main() {
    // Создание двух входных каналов
    c1 := generator(1, 2, 3)
    c2 := generator(4, 5, 6)
​
    // Объединение входных каналов в один
    for n := range fanIn(c1, c2) {
        fmt.Println(n)
    }
}

Объяснение:

  • generator — функция, создающая канал, из которого можно читать данные.
  • fanIn — функция, объединяющая несколько входных каналов в один выходной канал.
  • output — функция, читающая из входного канала и записывающая в выходной канал.
  • main — функция, где создаются два входных канала и объединяются в один с помощью fanIn.

Применение

Fan-in и fan-out паттерны широко применяются в системах, где требуется высокая производительность и параллельная обработка данных. Они позволяют эффективно распределять нагрузку между несколькими горутинами и собирать результаты в одном месте, что упрощает управление потоками данных и улучшает масштабируемость приложений.

Тема: Конкурентность
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки