Этапы конвейера
Связывайте этапы через каналы
«Этапы конвейера» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Что такое конвейер
Конвейер — это последовательность stage, соединённых каналами. Каждый stage получает значения, выполняет работу и отправляет результаты дальше по конвейеру. Данные движутся подобно изделиям на сборочной линии.
- Каждый stage является горутиной
- Stage взаимодействуют только через каналы
- Их легко объединять и анализировать
Соглашение о сигнатуре stage
По соглашению каждый stage принимает один или несколько входных каналов, доступных только для чтения, и возвращает выходной канал, доступный только для чтения. Благодаря этому stage можно объединять в цепочку.
func stage(in <-chan int) <-chan int {
out := make(chan int)
go func() {
defer close(out)
for v := range in {
out <- v
}
}()
return out
}Исходный stage
Первый stage создаёт данные. Часто он принимает срез или переменное число аргументов и передаёт их в канал по мере поступления.
func numbers(vals ...int) <-chan int {
out := make(chan int)
go func() {
defer close(out)
for _, v := range vals {
out <- v
}
}()
return out
}Stage преобразования
Этот stage умножает каждое значение на десять. Он читает данные из in и записывает преобразованное значение в out.
func tenfold(in <-chan int) <-chan int {
out := make(chan int)
go func() {
defer close(out)
for v := range in {
out <- v * 10
}
}()
return out
}Stage фильтрации
Фильтр передаёт дальше только значения, удовлетворяющие условию. Здесь мы оставляем чётные числа, а остальные отбрасываем.
func evens(in <-chan int) <-chan int {
out := make(chan int)
go func() {
defer close(out)
for v := range in {
if v%2 == 0 {
out <- v
}
}
}()
return out
}Объединение stage в цепочку
Составляйте цепочки stage, передавая выход одного stage в качестве входа следующего. Такая цепочка почти читается как предложение.
pipe := tenfold(evens(numbers(1, 2, 3, 4)))
for v := range pipe {
fmt.Println(v)
}defer close(out)
Использование defer close(out) гарантирует закрытие выходного канала при возврате горутины stage, даже если позже Вы добавите досрочные возвраты. Это передаёт сигнал об окончании потока дальше по конвейеру.
Полный конвейер
Сначала источник, затем фильтр, затем преобразование. Запустите программу, чтобы увидеть результат умножения на десять только для чётных входных значений.
package main
import "fmt"
func numbers(vals ...int) <-chan int {
out := make(chan int)
go func() { defer close(out); for _, v := range vals { out <- v } }()
return out
}
func evens(in <-chan int) <-chan int {
out := make(chan int)
go func() { defer close(out); for v := range in { if v%2 == 0 { out <- v } } }()
return out
}
func tenfold(in <-chan int) <-chan int {
out := make(chan int)
go func() { defer close(out); for v := range in { out <- v * 10 } }()
return out
}
func main() {
for v := range tenfold(evens(numbers(1, 2, 3, 4, 5, 6))) {
fmt.Println(v)
}
}Потоковая обработка, а не пакетная
Значения проходят через конвейер по одному по мере создания. Stage преобразования может начать обработку первого элемента ещё до того, как источник выдаст последний. Это позволяет использовать мало памяти и уменьшает задержку.
Конвейеры ленивы
Stage не выполняет работу, пока кто-то не читает из его выходного канала. Если потребитель перестаёт перебирать канал, вышестоящие stage блокируются при отправке данных. Это естественное обратное давление предотвращает напрасные вычисления.
Добавление параллелизма
Чтобы ускорить медленный stage, распределите его работу между несколькими экземплярами, читающими из одного входа, и объедините их выходы. Сигнатура stage остаётся прежней, меняется только соединение компонентов.
Быстрая проверка
Проверьте, насколько хорошо Вы понимаете конвейеры.
Итоги
Вы изучили stage конвейера:
- Каждый stage получает вход, доступный только для чтения, и возвращает выход, доступный только для чтения
- defer close(out) передаёт сигнал об окончании потока дальше
- Объединяйте stage в цепочку, вкладывая вызовы
- Конвейеры лениво передают данные и создают обратное давление
Изучай Go с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 51
- Уроки
- 203
Часто задаваемые вопросы
Урок «Этапы конвейера» бесплатный?
Да — полный текст урока «Этапы конвейера» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Этапы конвейера»?
Связывайте этапы через каналы Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Этапы конвейера»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Паттерн пула работников
- Fan-Out и Fan-In
- Этапы конвейера
- Корректное завершение