Содержание
00:00:00В этом видеоуроке мы начнем знакомиться с каналами. В этом уроке мы рассмотрим различные аспекты работы каналов.
Определение и назначение каналов
00:00:25Каналы - это средства коммуникации, которые позволяют осуществлять обмен данными между различными объектами. Они могут использоваться для отправки и получения данных определенного типа. Внутри канала есть буфер, который помогает ускорить обработку. Существует также два типа очередей: очередь чтения для потребителей и очередь записи для производителей.
Nil`овый канал
00:02:05В этой главе мы узнаем, как создать новый канал. Это так же просто, как объявить переменную с ключевым словом "channel" и указать тип данных, которые будут передаваться через нее.
len и cap канала
00:02:36Длина канала относится к количеству элементов, находящихся в данный момент в его буфере. Емкость, с другой стороны, представляет собой размер буфера. Когда мы создаем новый канал, его длина и пропускная способность изначально равны нулю. Это означает, что в буфере нет элементов, с ним не связаны мьютексы или переменные условия.
Запись и чтение из каналов
00:03:25Для записи и извлечения значений из каналов используется специальный оператор, называемый "look". В зависимости от того, написана ли стрелка слева или справа от канала, ее значение меняется. Например, если стрелка находится с правой стороны канала, это означает, что мы помещаем туда значение. Важная вещь, которую нужно знать об одноканальном устройстве, - это как организовать его запись и извлечение.
Deadlock
00:04:03Взаимоблокировка возникает, когда программа зависает из-за того, что она ожидает выполнения определенных условий, но эти условия никогда не будут выполнены. Это происходит, когда программа полагается на определенную последовательность событий, которые не могут произойти на нашем канале. В результате программа зависает, и среда выполнения обнаруживает эту ситуацию и завершает ее, чтобы предотвратить неопределенное зависание.
Закрытие каналов (close)
00:05:13Процесс закрытия каналов завершился ошибкой. Давайте обсудим следующую операцию, которую можно выполнить с каналами. Каналы могут быть закрыты и дальше, и я объясню, почему это необходимо. А пока позвольте мне привести вам пример, используя неуклюжую аналогию: представьте, что существует специальная функция под названием "Клаус", которая принимает канал в качестве входных данных. В данном случае мы пытаемся закрыть наш канал "melovii". Давайте запустим его и посмотрим, что получится. Как вы можете видеть, мы столкнулись с паникой, потому что новый канал не может быть закрыт, если продолжается анализ его контента. Этот конкретный канал вряд ли когда-нибудь нам пригодится; значения не могут быть записаны или прочитаны из него, как только он закрыт с помощью обычного объявления переменной. Таким образом, по сути, создавая такой канал с помощью обычного объявления переменной, подобного этому (ссылаясь на предыдущий код), вы не получите выгоды от использования каналов.
Небуферизованный канал (unbuffered channel)
00:06:01Небуферизованный канал Небуферизованный канал - это тип канала, у которого нет буфера. Когда мы создаем небуферизованный канал с помощью функции make, мы указываем тип значения, которое будет передаваться через него. Размер и пропускная способность канала равны нулю, что означает, что буферизация не используется.
Операции "чтения" и "записи" по небуферизованным каналам Операции "чтения" и "записи" в небуферизованном канале требуют одновременного присутствия как считывателя, так и записывающего устройства для обмена данными. Если в данный момент времени нет доступных устройств записи или считывания, операция блокируется до тех пор, пока они не станут доступными.
Обменивайтесь данными по небуферизованным каналам Для обмена данными с небуферизованным каналом вам понадобятся как минимум две подпрограммы: одна для записи (отправитель) и другая для чтения (получатель). И отправитель, и получатель должны пытаться установить связь одновременно, иначе они заблокируют друг друга
Работа с каналом после его закрытия
00:11:45Работа с закрытыми каналами После закрытия канала важно понять, как он работает. Давайте запустим наш код и посмотрим, что произойдет. Мы сталкиваемся с ошибкой при попытке отправить данные после закрытия канала, потому что нам заблокирована запись в закрытый канал. Кроме того, существует задержка в полсекунды перед закрытием канала с помощью функции "закрыть" и еще одна задержка в полсекунды перед попыткой считывания из закрытого канала. Только в этот момент должна произойти запись, но помните, что как только канал закрыт, больше никаких записей быть не может.
Еще одна важная вещь, которую следует отметить, заключается в том, что если вы попытаетесь снова закрыть уже закрытую chanel, возникнет паника.
Направленность каналов
00:13:24Каналы могут быть направлены как для записи, так и для чтения. У нас есть два способа создать канал: один предназначен исключительно для записи, а другой - исключительно для чтения. В некоторых случаях нам может потребоваться использовать определенный канал только для записи данных или только для извлечения данных.
Буферизованный канал (buffered channel)
00:15:13Буферизованные каналы Буферизованный канал позволяет нам создать канал с заданным размером буфера. Размер буфера определяет, сколько значений может содержать канал до его блокировки. В отличие от небуферизованного канала, где каждое значение немедленно передается и блокируется, если нет получателя, буферизованный канал может хранить несколько значений без блокировки.
Канал "bufere zero van" Каналы "Bufere zero van" аналогичны обычным каналам, но имеют буфер размером 0. Это означает, что они не блокируются при записи до тех пор, пока буфер не заполнится, или при чтении до тех пор, пока буфер не опустеет.
Различия между буферизованными каналами и каналами "bufere zero van" Основное различие между буферизованными каналами и каналами "bufere zero van" заключается в их поведении при записи или чтении данных. Буферизованные каналы допускают многократную запись без блокировки, пока в буфере есть свободное место, в то время как каналы "bufere zero van" допускают только одну запись за раз, поскольку их буферы всегда пусты.
Циклы по каналам
00:20:46В этой главе мы исследуем концепцию использования циклов для извлечения значений из каналов. Мы начинаем с того, что представляем себе канал с неизвестными значениями и внешний источник, который предоставляет эти значения. Затем мы создаем буферный канал для хранения входящих значений и считываем их одно за другим в бесконечном цикле. Однако возникает проблема, когда наш буферный канал достигает своей максимальной емкости в три элемента. Чтобы преодолеть эту проблему, мы используем буферизацию фиксированного размера, при которой новые значения перезаписывают старые в буфере.
Для чего нужно закрывать каналы?
00:23:25Закрытие канала необходимо для сообщения о том, что в канале больше не будет данных. Закрыв канал, мы можем эффективно сигнализировать об окончании нашей записи и предотвратить любую дальнейшую обработку или выполнение.
Чтение из закрытого канала
00:24:05Когда мы закрываем наш канал, считывание данных с него все еще возможно. Однако есть важная характеристика, которую необходимо понять: когда мы пытаемся считать значение из закрытого канала, значение, которое было введено в него, больше не существует. Вместо этого мы получаем значение по умолчанию этого типа.
Проверка на закрытие канала
00:24:42Чтобы проверить, закрыт ли канал, мы можем использовать значение канала по умолчанию. Считывая значение из канала, мы можем определить, был ли он закрыт или нет. Для этого нам нужны две переменные: одна для хранения текущего значения канала, а другая для указания, открыт он или закрыт. Если мы видим, что наш канал уже закрыт, то мы останавливаем наш цикл и продолжаем нашу программу.
For .. range для итерации по каналам
00:26:24"Для диапазона" - это удобный способ перебора каналов. Это позволяет нам считывать значения из канала до тех пор, пока он не будет закрыт. Используя "для каждого", мы можем избежать бесконечного считывания значений и гарантировать, что цикл завершается при закрытии канала.
Какой тип каналов использовать?
00:29:05При выборе каналов важно учитывать их пропускную способность и избегать их перегрузки. Понимая ожидаемый объем данных, вы можете создавать каналы с нулевой буферизацией с соответствующими буферами.
Мы сделали это
00:29:24Мы разработали программу, которая уменьшит блокировку и повысит скорость. Мы изучили различные теории о каналах, изучили их внутреннюю структуру и обнаружили, как замороженные каналы блокируются, в то время как буферизованные - нет. Это понимание часто отсутствует в учебниках. В следующем видеоуроке мы продолжим изучение каналов и рассмотрим различные варианты использования. Я также покажу вам примеры кода, использующего один и тот же пакет, но с разными методами использования каналов.