Найти в Дзене

#20 Как слить n каналов в один в Go

Одна из самых популярных задач на каналы. Условие Даны n каналов типа int. Нужно написать функцию, которая сольет (смержит) все данные из этих каналов в один и вернет его. Решение Напишем сигнатуру функции merge, которая принимает любое количество каналов типа int на вход и возвращает результирующий канал того же типа. resultChannel сделаем с буфером 1, не обязательно, но так мы уменьшим количество переключений между горутинами. Чтобы не забыть, сразу закроем результирующий канал в отдельной горутине. В функции main создадим три каналам в отдельных горутинах и запишем в них значения. Всего будет 6 цифр от 0 до 5. Также не забудем закрыть эти каналы - тот кто пишет в канал, тот и закрывает его. В теле функции merge в цикле итерируемся по каналам и асинхронно читаем все значения из низ каждого. range по каналу, останавливается, когда канал закрыт и из него нечего читать. Записываем каждое прочитанное значение из канала в resultChannel. Чтобы дождаться чтения из всех горутин нужно их с
Оглавление

Одна из самых популярных задач на каналы.

Условие

Даны n каналов типа int. Нужно написать функцию, которая сольет (смержит) все данные из этих каналов в один и вернет его.

Решение

Напишем сигнатуру функции merge, которая принимает любое количество каналов типа int на вход и возвращает результирующий канал того же типа. resultChannel сделаем с буфером 1, не обязательно, но так мы уменьшим количество переключений между горутинами. Чтобы не забыть, сразу закроем результирующий канал в отдельной горутине.

В функции main создадим три каналам в отдельных горутинах и запишем в них значения. Всего будет 6 цифр от 0 до 5. Также не забудем закрыть эти каналы - тот кто пишет в канал, тот и закрывает его.

В теле функции merge в цикле итерируемся по каналам и асинхронно читаем все значения из низ каждого. range по каналу, останавливается, когда канал закрыт и из него нечего читать. Записываем каждое прочитанное значение из канала в resultChannel.

-2

Чтобы дождаться чтения из всех горутин нужно их сихронизировать с помощью WaitGroup. Это задача похожа на рассмотренную ранее. Увеличиваем счетчик WaitGroup для каждой запущенной горутины. Их число равно количеству каналов. Внутри горутины с помощью defer wg.Done() декрементим счетчик. В той же горутине, в которой закрывали resultChannel, ждем завершения работы всех горутин через wg.Wait().

-3

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

ссылка на Playground