0Pricing
Go Academy · Урок

Шаблоны fan-in и fan-out

Объединение нескольких каналов и распределение работы

«Шаблоны fan-in и fan-out» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Что такое распределение

Распределение направляет работу из одного канала в несколько горутин, обеспечивая параллельную обработку. Каждый обработчик получает данные из одного и того же входного канала.

Пример распределения

Запустите N обработчиков, каждый из которых читает из общего канала заданий:

func fanOut(jobs <-chan Job, n int) {
    for i := 0; i < n; i++ {
        go func() {
            for job := range jobs {
                process(job)
            }
        }()
    }
}

Что такое сведение

Сведение объединяет несколько каналов в один, чтобы один потребитель мог читать результаты от множества производителей.

Сведение с помощью горутин

Запустите по одной горутине для каждого входного канала; каждая горутина будет передавать значения в общий выходной канал.

func fanIn(cs ...<-chan int) <-chan int {
    out := make(chan int)
    var wg sync.WaitGroup
    for _, c := range cs {
        wg.Add(1)
        go func(ch <-chan int) {
            defer wg.Done()
            for v := range ch { out <- v }
        }(c)
    }
    go func() { wg.Wait(); close(out) }()
    return out
}

Сведение с помощью select

Для фиксированного числа входных каналов цикл select проще, чем отдельная горутина для каждого канала.

func merge(a, b <-chan int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for a != nil || b != nil {
            select {
            case v, ok := <-a: if !ok { a = nil } else { out <- v }
            case v, ok := <-b: if !ok { b = nil } else { out <- v }
            }
        }
    }()
    return out
}

Этап конвейера

Объедините распределение и сведение, чтобы построить этап конвейера: один входной канал, N параллельных обработчиков и один объединённый выходной канал.

func parallelStage(in <-chan Work, n int) <-chan Result {
    outs := make([]<-chan Result, n)
    for i := 0; i < n; i++ {
        outs[i] = worker(in)
    }
    return fanIn(outs...)
}

Корректное закрытие каналов

Канал закрывает отправитель; получатель обнаруживает закрытие с помощью формы получения с двумя значениями или перебирая канал в цикле. Никогда не закрывайте канал со стороны получателя.

for v := range in { // exits when in is closed
    process(v)
}

Координация с помощью WaitGroup

Используйте sync.WaitGroup, чтобы определить момент завершения всех обработчиков распределения, а затем закройте выходной канал, чтобы последующие потребители могли завершить работу.

Обратное давление

Используйте буферизованные каналы между этапами конвейера, чтобы сглаживать всплески. Размер буфера определяйте с учётом ожидаемой разницы задержек между производителем и потребителем.

out := make(chan Result, 100) // buffer absorbs bursts

Передача ошибок

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

type Result struct {
    Value int
    Err   error
}

Отмена через контекст

Передавайте контекст через этапы конвейера и проверяйте ctx.Done() на каждом этапе, чтобы весь конвейер останавливался после отмены.

case <-ctx.Done():
    return ctx.Err()

Проверка знаний

В шаблоне сведения что закрывает объединённый выходной канал?

Итоги: сведение и распределение

Главное:

  • Распределение: несколько обработчиков читают из одного канала
  • Сведение: по одной горутине для каждого источника объединяют данные в один выходной канал
  • WaitGroup координирует закрытие объединённого канала
  • Для отмены используйте контекст, а для обратного давления — буферизованные каналы

Часто задаваемые вопросы

Урок «Шаблоны fan-in и fan-out» бесплатный?

Да — полный текст урока «Шаблоны fan-in и fan-out» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Шаблоны fan-in и fan-out»?

Объединение нескольких каналов и распределение работы Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Шаблоны fan-in и fan-out»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Оператор select
  2. Тайм-ауты и тикеры
  3. Шаблоны fan-in и fan-out
  4. Шаблон пула работников
← Назад к Go Academy