Шаг 65.
Язык программирования Go.
Пример использования канала
На этом шаге рассмотрим пример использования канала.
В примере реализуется функция createCounter(), возвращающая канал, через который в ответ на запрос
отправляется целое число. Первым будет принято начальное значение, переданное функции createCounter(), а каждое последующее
значение будет на единицу больше предыдущего. На рис. 1 показаны, результаты производимые
созданными двя независимыми каналами, каждый из которых действует в собственной go-подпрограмме.

Рис.1. Пример работы приложения
Раскрыть/скрыть решение и комментарии.
/*В главной go-подпрограмме выполняются два вызова функции createCounter(), и в
каждом из них создается новая go-подпрограмма, причем обе они изначально
заблокированы. Как только в главной go-подпрограмме производится попытка получить
данные из какого-либо канала, тут же выполняется передача, и программа получает
очередное значение. Затем передающая go-подпрограмма снова блокируется, ожидая
нового запроса от принимающей стороны. Эти два канала "бесконечны", в том смысле
что всегда готовы отправить очередное значение. При достижении верхнего предела
представления значений типа int произойдет переход к значению, равному нижнему
пределу. Как только из каждого канала будет получено по пять значений, они снова
заблокируются и будут пребывать в готовности к дальнейшему использованию.*/
func main() {
counterA := createCounter(10) // counterA имеет тип chan int
counterB := createCounter(2015) // counterB имеет тип chan int
for i := 0; i < 5; i++ {
a := <-counterA /*Первый способ приема данных из канала
присваивает принятое значение переменной */
fmt.Printf("(A->%d, B->%d) \n", a, <-counterB) /*Второй способ приема
данных из канала
передает принятое
значение функции
в виде аргумента*/
}
fmt.Println()
}
/*Функция createCounter() принимает начальное значение
и создает канал для передачи и приема целых чисел.*/
func createCounter(start int) chan int {
next := make(chan int)
go func(i int) {
for {
next <- i
i++
}
}(start)
return next
}
/*Она запускает анонимную функцию в новой go-подпрограмме, передавая ей
начальное значение. Функция выполняет бесконечный цикл, который в каждой
итерации просто отправляет целое число и затем увеличивает его на единицу.
Поскольку канал создан с нулевой емкостью, операция передачи блокируется,
пока не будет получен запрос от принимающей стороны. Блокируется только
анонимная функция в go-подпрограмме, а остальные go-подпрограммы в программе
продолжают выполняться. Как только go-подпрограмма будет запущена
(и тут же окажется заблокирована), немедленно будет выполнена следующая
инструкция в функции, возвращающая канал вызывающей программе.*/
Архив примера можно взять здесь.
В некоторых ситуациях может потребоваться запустить множество go-подпрограмм, и каждую с собственным каналом передачи
данных. Контролировать взаимодействия с ними можно с помощью
инструкции select.
На следующем шаге рассмотрим инструкцию select.
Предыдущий шаг
Содержание
Следующий шаг