Golang - Что такое размер буфера канала?
Я пытаюсь создать асинхронный канал, и я смотрю на http://golang.org/ref/spec.
c := make(chan int, 10) // channel with a buffer size of 10
Что это значит, что размер буфера равен 10? Что конкретно представляет / ограничивает размер буфера?
3 ответа
Размер буфера - это количество элементов, которые могут быть отправлены на канал без блокировки отправки. По умолчанию канал имеет размер буфера 0 (вы получаете это с make(chan int)
). Это означает, что каждая отправка будет блокироваться до тех пор, пока другая программа не получит данные из канала. Канал с размером буфера 1 может содержать 1 элемент до отправки блоков, так что вы получите
c := make(chan int, 1)
c <- 1 // doesn't block
c <- 2 // blocks until another goroutine receives from the channel
Следующий код иллюстрирует блокировку небуферизованного канала:
// to see the diff, change 0 to 1
c := make(chan struct{}, 0)
go func() {
time.Sleep(2 * time.Second)
<-c
}()
start := time.Now()
c <- struct{}{} // block, if channel size is 0
elapsed := time.Since(start)
fmt.Printf("Elapsed: %v\n", elapsed)
Вы можете поиграть с кодом здесь.
package main
import (
"fmt"
"time"
)
func receiver(ch <-chan int) {
time.Sleep(500 * time.Millisecond)
msg := <-ch
fmt.Printf("receive messages %d from the channel\n", msg)
}
func main() {
start := time.Now()
zero_buffer_ch := make(chan int, 0)
go receiver(zero_buffer_ch)
zero_buffer_ch <- 444
elapsed := time.Since(start)
fmt.Printf("Elapsed using zero_buffer channel: %v\n", elapsed)
restart := time.Now()
non_zero_buffer_ch := make(chan int, 1)
go receiver(non_zero_buffer_ch)
non_zero_buffer_ch <- 4444
reelapsed := time.Since(restart)
fmt.Printf("Elapsed using non zero_buffer channel: %v\n", reelapsed)
}
результат:
получать сообщения 444 с канала
Прошло с использованием канала zero_buffer: 505.6729ms
Прошло с использованием ненулевого канала: 0 с