Подтвердить что ты не робот

Когда использовать буферный канал?

Каковы случаи использования для буферизованных каналов? Если я хочу несколько параллельных действий, я мог бы просто использовать стандартное, синхронное уравнение канала

package main
import "fmt"
import "time"

func longLastingProcess(c chan string) {
    time.Sleep(2000 * time.Millisecond)
    c <- "tadaa"
}

func main() {
    c := make(chan string)
    go longLastingProcess(c)
    go longLastingProcess(c)
    go longLastingProcess(c)
    fmt.Println(<- c)
}

Каковы были бы практические случаи увеличения размера буфера?

4b9b3361

Ответ 1

Как правило, буферизация в каналах выгодна по соображениям производительности.

Если программа спроектирована с использованием подхода потока событий или потока данных, каналы предоставляют средства для прохождения событий между одним процессом и другим (я использую термин "процесс" в том же смысле, что и в Тони Хоар, сообщающем последовательные процессы (CSP), то есть эффективно синонимично с goroutine).

  • Бывают случаи, когда программе необходимо, чтобы ее компоненты оставались в синхронной блокировке. В этом случае необходимы небуферизованные каналы.

  • В противном случае обычно полезно добавлять буферизацию к каналам. Это следует рассматривать как шаг оптимизации (взаимоблокировка может быть возможна, если не разработана).

  • Появились новые структуры дроссельной заслонки, сделанные с использованием каналов с небольшими буферами (пример).

  • Существуют специальные формы перезаписи или потери данных, используемые в оккаме и jcsp для фиксации специального случая цикла (или цикла) процессов, которые в противном случае могли бы быть взаимоблокировками. Это также возможно в Go, написав буфер перезаписи goroutine (пример).

Вы не должны добавлять буферизацию, чтобы исправить тупик. Если ваша программа блокируется, ее гораздо легче исправить, начиная с нулевой буферизации и продумать зависимости. Затем добавьте буферизацию, когда вы знаете, что она не будет тупиковой.

Вы можете построить goroutines композиционно - то есть, goroutine может сам содержать goroutines. Это особенность CSP и значительно повышает масштабируемость. Внутренние каналы между группой goroutines не представляют интереса при разработке внешнего использования группы в качестве автономного компонента. Этот принцип может применяться неоднократно при все более широких масштабах.

Ответ 2

Чтобы дать один, немного более конкретный вариант использования:

Предположим, что вы хотите, чтобы ваш канал представлял очередь задач, так что планировщик задач может отправлять задания в очередь, а рабочий поток может использовать задание, получая его в канале.

Предположим далее, что, хотя в целом вы ожидаете, что каждое задание будет обработано своевременно, для выполнения задачи требуется больше времени, чем для планировщика, чтобы запланировать его.

Наличие буфера позволяет планировщику задавать задания в очереди и по-прежнему реагировать на ввод пользователя (или сетевой трафик или что-то еще), потому что ему не нужно спать, пока рабочий не будет готов каждый раз при планировании задачи. Вместо этого он идет о своем бизнесе и доверяет рабочим догонять в более спокойный период.

Если вам нужен пример EVEN MORE CONCRETE, посвященный конкретному программному обеспечению, тогда я посмотрю, что я могу сделать, но надеюсь, что это соответствует вашим потребностям.

Ответ 3

Буферизованные каналы не блокируются для отправителя, если есть еще место. Это может увеличить скорость реагирования и пропускную способность.

Отправка нескольких элементов на один буферный канал гарантирует, что они обрабатываются в том порядке, в котором они отправлены.

От эффективного Go (с примера): " Буферизованный канал может использоваться как семафор, например, для ограничения пропускной способности."

В общем, существует много вариантов использования и шаблонов использования канала, поэтому это не исчерпывающий ответ.

Ответ 4

Если приемник канала всегда медленнее, чем отправитель, в конечном итоге будет потребляться буфер любого размера. Это оставит вас с каналом, который приостанавливает вашу рутину так часто, как небуферизованный канал, чтобы вы могли использовать небуферизованный канал.

Если приемник обычно быстрее, чем отправитель, за исключением случайного всплеска, буферный канал может быть полезным, и буфер должен быть установлен на размер типичного пакета, который вы можете получить путем измерения во время выполнения.

В качестве альтернативы буферизованному каналу лучше всего отправить массив или структуру, содержащую массив по каналу, для обработки пакетов/пакетов.

Ответ 5

Трудный вопрос b/c неверен: он выходит после приема сигнала от одного goroutine, но три были запущены. Буферизация канала ничем не отличается.

EDIT: Например, здесь немного обсуждается канал буферы. И некоторые упражнение. И глава книги о том же.