Kích thước bộ đệm kênh là gì?


82

Tôi đang cố tạo một kênh không đồng bộ và tôi đã xem tại http://golang.org/ref/spec#Making_slices_maps_and_channels .

c := make(chan int, 10)         // channel with a buffer size of 10

Điều đó có nghĩa là kích thước bộ đệm là 10? Cụ thể kích thước bộ đệm đại diện cho điều gì / giới hạn?


Xem ở đây và hơn thế nữa
Ivan Black

Xem ở đây cũng hữu ích. Rất thẳng và dễ hiểu :)
Ardi Nusawan

Câu trả lời:


157

Kích thước bộ đệm là số phần tử có thể được gửi đến kênh mà không bị chặn gửi. Theo mặc định, một kênh có kích thước bộ đệm là 0 (bạn nhận được điều này với make(chan int)). Điều này có nghĩa là mỗi lần gửi sẽ bị chặn cho đến khi một quy trình khác nhận được từ kênh. Một kênh có kích thước bộ đệm 1 có thể chứa 1 phần tử cho đến khi gửi khối, vì vậy bạn sẽ nhận được

c := make(chan int, 1)
c <- 1 // doesn't block
c <- 2 // blocks until another goroutine receives from the channel

21
Câu trả lời tốt. Cờ vây hiệu quả có một chương hay có tựa đề "Đồng thời" có trên các kênh. Rất khuyến khích: golang.org/doc/effective_go.html
Levi

Tôi đang bối rối với điều này và làm cho (chan int, 1) cho phép 3 giá trị được chuyển vào kênh của tôi trước khi chặn (kiểm tra nó với log.Printlns) và mặc định là cho phép 2 giá trị trước khi chặn. Bất kỳ ý tưởng tại sao:
Mauricio

@Mauricio Điều đó nghe có vẻ khá kỳ lạ. Tôi vừa thử nghiệm bằng cách sử dụng Go 1.8.3 cục bộ và cũng sử dụng chức năng "Thử bắt đầu" tại golang.org và trong cả hai trường hợp, nó vẫn hoạt động như được ghi trong câu trả lời của tôi.
Lily Ballard

1
Tôi đánh giá cao phản hồi, nhưng thực sự tôi đã hiểu sai việc in dữ liệu sang bảng điều khiển của mình. Nó hoạt động như bạn đã mô tả.
Mauricio

10

Đoạn mã sau minh họa việc chặn kênh không có bộ đệm:

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

Bạn có thể chơi với mã ở đây .


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

kết quả:

nhận tin nhắn 444 từ kênh

Đã trôi qua bằng kênh zero_buffer: 505,6729ms

Đã trôi qua bằng cách sử dụng kênh non zero_buffer: 0 giây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.