Шаг 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.
Предыдущий шаг  Содержание
Содержание  Следующий шаг
Следующий шаг