[БЕЗ_ЗВУКА] В этом видео мы поговорим о мультиплексировании каналов при помощи инструкции select. Часто бывают случаи, когда нам нужно опрашивать несколько каналов, но мы не можем делать это последовательно или хотя бы в цикле, потому что тогда они заблокируются, если они еще не готовы. Для того, чтобы опрашивать несколько каналов, есть специальная инструкция select. Давайте посмотрим, как она работает. Итак, у нас есть два канала, которые не буферизированы, и инструкция select. Select очень похожа на switch, однако в ней в качестве случаев для case выступают не логические, то есть булевы выражения, а операции над каналами. Вы можете как читать из канала какое-то значение, так и писать в канал. И есть оператор default, который выполняется в том случае, если никакого из других операторов... никакой из других случаев не ответил, то есть канал заблокирован. Давайте запустим эту программу. Смотрите, выполнился default case. Почему? Потому что у нас ни в одном из каналов не было значения. То есть в первом канале, откуда мы пытались прочитать, ничего не было, второй канал, куда мы что-то попытались записать, из него никто не читал, и как бы он тоже был заблокирован. Теперь давайте сделаем один из каналов буферизированным, и положим туда какое-то значение. [ЗВУК] И запустим заново. Смотрите, сейчас выполнится случай, когда мы пытались прочитать что-то из канала 1, и он нам напечатался. Если случая default не будет, и при этом никакой канал не будет готов, то наступит ситуация deadlock. [ЗВУК] Deadlock, то есть никакой из каналов не прочитан, и мы ждем, то есть с той стороны тоже никто не пишет. Вот. Давайте посмотрим, что с этим можно дальше сделать. Вот у нас есть такая программа. То есть мы можем читать из этих каналов. Давайте посмотрим, как это происходит. За раз внутри select выполняется только одна операция, то есть это не происходит так, что select сам опросил несколько каналов и каждый из них выполнил, нет. Если мы хотим, чтобы попытки опроса каналов происходили еще, то нам приходится делать цикл. Давайте посмотрим, как это работает. Создадим два канала. В каждый из них положим по несколько значений. Теперь внутри цикла мы будем опрашивать эти каналы, если там что-то есть, мы будем выводить это на экран. А если ничего нам не вернется, то мы завершим цикл, используя break и метку цикла. Мы не можем написать просто break, потому что в этом случае мы завершим select, поэтому нужна метка цикла. Давайте запустим. [ЗВУК] [ЗВУК] Вот посмотрите. Мы прочитали из канала 1, потом из канала 2 и затем еще раз из канала 1. Какой из каналов выбирать для чтения, планировщик Go выбирает случайным образом, мы это контролировать не можем. То есть они выполняются не в том порядке, в котором мы их указали внутри select. Хорошо. Мы разобрались с чтением из каналов. Но мы можем не только... в рамках одного select мы можем не только читать из разных каналов, но и читать и писать. И это открывает нам возможность для того, чтобы завершать какие-то внешние каналы, внешние функции, используя так называемый канал отмены. Давайте посмотрим, как это работает. Итак, у нас есть два канала. Первый канал — канал отмены, в него мы можем класть пустую структуру. Пустая структура — это структура без полей, она не занимает места, то есть как бы... только сам признак, что там что-то есть. Ну и канал с данными. Теперь вызовем функцию, которая будет бесконечно нам печатать значения. Ну как бесконечно? Внутри этой функции будет бесконечный цикл. И внутри этого цикла будет select с несколькими case-ами. Первый case выполняется только если мы что-то прочитали из канала отмены, какого-то внешнего канала. В этом случае мы завершим работу всей функции. В противном случае мы будем писать в канал с данными увеличивающиеся значения. Ну и теперь давайте попробуем итерироваться по этому каналу со значениями — data Сhannel. Смотрите, мы итерируемся, пишем, что мы что-то прочитали. Если то, что мы прочитали, больше 3, тогда мы отправим в канал с отменой пустую структуру, то есть сам признак того, что туда что-то положили. Когда это произойдет, когда это произойдет на строчке 27, это значение прочитается из канала на строчке 15. То есть нам не важно само значение, нам важен сам факт, что было что-то прочитано. Как только этот факт случился, то мы просто завершаем выполнение функции. Давайте посмотрим, как это будет работать. [ЗВУК] Посмотрите. Мы напечатали пять значений. Как только значение, которое нам пришло, стало больше 3, да, то есть 4, текущее значение больше 3, мы написали, что мы шлем отмену и завершили цикл. Все. В этом видео мы посмотрели, как можно мультиплексировать каналы, как можно читать из нескольких каналов, как использовать мультиплексор select для того, чтобы завершить работу канала. В следующем видео мы посмотрим, какие другие функции Go предоставляет для удобного... удобной работы с таймингами и завершением каналов.