2013-02-27 3 views
20

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

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) 
} 

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

ответ

0

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

EDIT: Например, здесь немного обсуждается канал buffers. И некоторые exercise. И book chapter примерно такой же.

+0

Эй, речь идет о сценариях реальной жизни для буферизованных каналов. Приведенный выше пример - это просто пример. – Dante

+0

Использование буферизованных каналов в значительной степени зависит от выполняемой задачи. См. Обновленный ответ. – zzzz

3

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

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

От эффективной Go (с примером): «A buffered channel can be used like a semaphore, for instance to limit throughput.»

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

8

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

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

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

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

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

12

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

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

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

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

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

  • Есть специальную перезапись или с потерями формы каналов, используемых в Оккама и JCSP для фиксации специального случая цикла (или цикла) процессов, которые бы в противном случае, вероятно, взаимоблокировку. Это также возможно в Go, написав буфер перезаписи gotoutine (example).

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

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

+2

Они также могут использоваться для обеспечения выхода goroutine, например, в 'time.After' он используется таким образом, что независимо от того, ожидает ли клиент значение, он может отправлять и возвращать. Буферизация также используется, например, клиенты пакета 'os/signal', поскольку API не может блокировать уведомления. –

2

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

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

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

Смежные вопросы