cpp

Каналы. Оператор select

Оператор select позволяет дождаться появления данных в одном из каналов. Оператор имеет следующий формат:

select {
case Переменная := <-Канал_1:
   Инструкции
[...
case Переменная := <-Канал_N:
   Инструкции]
[default:
   Инструкции]
}

Если указаны только блоки case, то текущий поток блокируется до появления данных в каком-либо канале (листинг 18.17). Если в нескольких каналах одновременно появляются данные, то будет чтение из любого одного из них. Какого именно, предсказать нельзя. Из первого доступного канала.

Листинг 18.17. Оператор select

package main

import (
   "fmt"
   "time"
)

func main() {
   ch := make(chan int)
   ch2 := make(chan int)
   go func() {
      time.Sleep(time.Second * 2)
      ch <- 10
   }()
   go func() {
      time.Sleep(time.Second * 5)
      ch2 <- 20
   }()
   select {
   case v := <-ch:
      fmt.Println("ch:", v)
   case v := <-ch2:
      fmt.Println("ch2:", v)
   }
   fmt.Println("Конец функции main()")
}

Пока в каком-либо канале не появятся данные, поток внутри функции main() будет блокирован. Первая функция запишет первой данные в канал ch, поэтому получим такой результат:

ch: 10
Конец функции main()

Если мы переделаем первую функцию следующим образом:

go func() {
   time.Sleep(time.Second * 12)
   ch <- 10
}()

то вторая функция запишет первой данные в канал ch2, поэтому получим следующий результат:

ch2: 20
Конец функции main()

В итоге мы получаем данные только из одного канала. Того, в котором данные появятся первыми.

Если существует блок default, то текущий поток при отсутствии данных внутри каналов блокироваться не будет. В этом случае выполняются инструкции внутри блока default и происходит выход из оператора select. Давайте изменим код оператора select из листинга 18.17 следующим образом:

select {
case v := <-ch:
   fmt.Println("ch:", v)
case v := <-ch2:
   fmt.Println("ch2:", v)
default:
   fmt.Println("Каналы не содержат данных")
}

В итоге получим следующий результат:

Каналы не содержат данных
Конец функции main()

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp