UblGO / go-project-sprint-9

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Комментарии к фрагментам кода

1. Функция Generator

Функция должна генерировать числа и записывать их в канал ch. Для каждого числа должна быть вызвана функция fn(). Используйте такой алгоритм генерации:

- N(0) = 1;
- N(i) = N(i-1) + 1

Generator() прекращает работу, когда поступил сигнал об отмене контекста ctx.

Подсказка 1

Используйте бесконечный цикл for и конструкцию select с проверкой на <-ctx.Done(). Перед выходом из функции закройте канал ch.

2. Функция Worker()

Эта функция обрабатывает числа. Она должна читать числа из канала in до тех пор, пока он не закроется. Полученное число нужно записать в канал out и сделать паузу на 1 миллисекунду. Если канал in закрылся, то нужно закрыть канал out и завершить работу функции.

Подсказка 2

Можно использовать бесконечный цикл и оператор v, ok := <-in, который позволяет отследить закрытие канала.

3. Создание контекста

Здесь необходимо создать контекст ctx, который должен самостоятельно отмениться через одну секунду.

Подсказка 3

Используйте context.WithTimeout() и не оставляйте cancel() без присмотра.

4. Собираем числа из каналов outs

В этом фрагменте нужно пройтись по всем каналам из слайса outs и для каждого из них запустить горутину с анонимной функцией. Горутина должна читать данные из переданного ей канала, до тех пор, пока он не закроется. Чтобы дождаться завершения всех этих горутин, нужно воспользоваться механизмом WaitGroup. Горутина должна подсчитывать обработанные числа (увеличивать соответствующий счётчик в слайсе amounts) передавать значения в канал chOut.

Подсказка 4

Перед вызовом горутины не забудьте вызвать wg.Add(1), а при её завершении — wg.Done(). Используйте анонимную функцию с двумя параметрами go func(in <-chan int64, i int64){}, где in — очередной канал из outs, а i — его индекс. Не забывайте про увеличение счётчика amounts[i]++.

5. Читаем числа из результирующего канала

Осталось прочитать все данные из канала chOut. При этом нужно подсчитать в переменной count общее количество чисел, а в переменной sum — сумму всех чисел.

Подсказка 5

Воспользуйтесь конструкцией for ... range, которая будет читать числа из канала до его закрытия.

6. Исправляем потенциальное состояние гонки

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

Читать дальше

Состояние гонки в основном возникает, когда несколько горутин одновременно изменяют общие данные. Посмотрите внимательно на код программы. Предположим, кто-то решит запускать несколько горутин для генерации чисел. Это может привести к состоянию гонки: анонимная функция, которая передаётся в Generator(), изменяет одни и те же переменные — inputSum и inputCount. Сделайте увеличение этих переменных потокобезопасным. Вы можете использовать мьютекс или функцию atomic.AddInt64().

Проверка результатов

После добавления необходимого кода и успешной отработки, программа должна вывести в консоль примерно такие строки:

Количество чисел 4558 4558
Сумма чисел 10389961 10389961
Разбивка по каналам [913 912 913 910 910]

У вас значения будут другими, но числа в первой и второй строчках, которые указаны через пробел, должны совпадать. Числа слайса amount должны быть практически одинаковыми. Они показывают, сколько значений передалось через соответствующий канал outs[i]. Если через один канал прошло, например, 800 чисел, а через другой — 900, это сигнал о неполадках. Вы можете изменить значение константы NumOut и сравнить результаты при NumOut, равной 2, 5, 10, 15. Видно, что чем больше используется горутин, тем больше чисел обрабатывается в сумме, но при этом каждая горутина обрабатывает меньше чисел. Вот пример вывода при NumOut, равной 15:

Количество чисел 13087 13087
Сумма чисел 85641328 85641328
Разбивка по каналам [870 873 873 873 873 873 872 872 874 872 871 872 874 871 874]

Если программа выдаёт ожидаемые результаты, можно отправлять её на ревью. Надеемся, что итоговое задание напомнило вам основные конструкции и инструменты работы с многопоточностью, и вы закрепили полученные знания на практике.

About


Languages

Language:Go 100.0%