チャネルバッファサイズとは何ですか?


86

非同期チャネルを作成しようとしていますが、http://golang.org/ref/spec#Making_slices_maps_and_channelsを見てきました。

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

バッファサイズが10とはどういう意味ですか?バッファサイズは具体的に何を表しますか/制限しますか?


こことさらに見る
Ivan Black

参照してください。ここにも役立ちます。非常にまっすぐで理解しやすい:)
Ardi Nusawan 2018年

回答:


161

バッファサイズは、送信をブロックせずにチャネルに送信できる要素の数です。デフォルトでは、チャネルのバッファサイズは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

21
いい答えです。Effective Goには、チャネルについて説明する「同時実行性」というタイトルのすばらしい章があります。強くお勧めします:golang.org/doc/effective_go.html
Levi

これをいじって、make(chan int、1)を使用すると、ブロックする前に3つの値をチャネルに渡すことができます(log.Printlnsでテストします)。デフォルトでは、ブロックする前に2を入力します。理由:
Mauricio 2017年

@Mauricioそれはかなり奇妙に聞こえます。Go 1.8.3をローカルで使用し、golang.orgのTryGo」機能も使用してテストしましたが、どちらの場合も、回答に記載されているとおりに動作します。
リリーバラード2017年

1
応答に感謝しますが、実際にはコンソールへのデータ印刷を誤って解釈していました。あなたが説明したように動作します。
マウリシオ2017年

10

次のコードは、バッファリングされていないチャネルのブロックを示しています。

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

ここのコード遊ぶことができます


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

結果:

チャネルからメッセージ444を受信する

zero_bufferチャネルを使用して経過:505.6729ms

zero_buffer以外のチャネルを使用して経過:0秒

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.