При работе с Golang мы используем каналы, чтобы упростить работу без рутинных операций.
Это самый простой пример использования канала
Https://play.golang.org/p/iy9QealMxcT Ссылка на игровую площадку для этой цели.
В этом примере вы знаете, сколько integers
вы отправляете на канал и сколько получаете.
строка 12: numberCh <-i
означает, что мы отправляем целое число на канал
строка 16: <- numberCh
означает, что мы получаем значение из канала
Это также можно использовать для присвоения целого числа переменной, например:
newNumber := <- numberCh
Каналы такого типа называются буферизованными, и вы знаете, сколько каналов нужно создать и с которых нужно читать.
Но использование таких каналов не имеет никакого отношения к запуску простого цикла for
. Каналы полезны при работе с подпрограммами go, потому что go может порождать собственный процесс для операции, которая делает возможной параллельную обработку, которая, в свою очередь, заставляет программы запускаться одновременно и ускоряет нашу программу.
Итак, чтобы использовать подпрограммы go, нам просто нужно обернуть циклы внутри функции и добавить ключевое слово go
перед циклом. Итак, наш код будет.
Ссылка на игровую площадку для игры https://play.golang.org/p/kAxw-8yAEb9
Если вы запустите эту программу, вы увидите, что она ничего не печатает, но программа успешно завершается и завершается, потому что мы запускаем три разных потока для этой программы.
- Основной поток, выполняющий всю программу
- В строке 11 мы создаем новый поток для отправки целого числа на наш канал.
- Из строки 18 новый поток для получения целого числа, отправленного на канал.
Основные потоки успешно запускаются и завершаются, и он не ждет других подпрограмм. Второй и третий потоки выполняются, но не завершаются до завершения основного потока, поэтому печать не выполняется.
Если вы пришли с javascript, вы уже видели это раньше. Решением в javascript для было бы либо сделать его обещанием и дождаться разрешения обещания, либо использовать aysnc
await
. Можем ли мы сделать это на Голанге?
Ну конечно; естественно.
В Голанге есть штука под названием WaitGroup
, которая помогает нам в этом.
Ссылка на площадку для этого кода https://play.golang.org/p/6ZuRLVg8tzb
Теперь вы можете увидеть фактические результаты в программах. Это в точности похоже на javacsript waitAll
.
Но действительно ли это работает одновременно? Вы можете видеть только напечатанное число и также в порядке возрастания. Это не совсем похоже на меня. Давайте немного изменим программу, чтобы увидеть, как она работает одновременно.
Ссылка для перехода на игровую площадку для этого кода https://play.golang.org/p/LfLtaE7nGQB
Мы увеличили количество каналов до 50 и просмотрели 50 номеров.
В строке 19 мы печатаем номер, который отправляем.
В строке 27 мы печатаем полученный номер.
Результат для этого выглядит примерно так
Он случайным образом получает и отправляет номер. Он не ждет, пока завершится первая процедура, чтобы начать получать номера.
Это очень простая реализация каналов в Golang для работы с подпрограммами и каналами go. В следующей части мы узнаем, как справляться с ошибками в go-рутине.