Help us understand the problem. What is going on with this article?

Go のバッファ付きチャネル close の挙動

More than 3 years have passed since last update.

バッファ付きチャネルをcloseするとどうなるか

突然ですが、次のプログラムを動かした時の出力を答えてください。

package main

import "fmt"

func main() {
    // バッファ 2 のチャネル
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    close(ch)

    for n := range ch {
        fmt.Println(n)
    }
}

正解はこちら
https://play.golang.org/p/mDvIj--7zC

1
2

Program exited.

先にcloseされていますが、バッファに残っている値はすべてちゃんと読みだしてからcloseを判断しているようです。

チャネルの受信側には、すべての値が読み出されてから close 通知がくる

次のプログラムを動かして見ましょう

package main

import "fmt"

func main() {
    // バッファ 3 のチャネル
    ch := make(chan int, 3)
    ch <- 1
    ch <- 2
    close(ch)

    n1, ok1 := <- ch
    n2, ok2 := <- ch
    _, ok3 := <- ch

    fmt.Println(n1, ok1)
    fmt.Println(n2, ok2)    
    fmt.Println(ok3)
}

https://play.golang.org/p/1CiCfR5mou

1 true
2 true
false

送信側からは、closeしたチャネルには値を送信できません

package main

func main() {
    // バッファ 3 のチャネル
    ch := make(chan int, 3)
    ch <- 1
    ch <- 2
    close(ch)

    ch <- 3
}

https://play.golang.org/p/yt3thjb8j7

panic: send on closed channel

goroutine 1 [running]:
main.main()
    /tmp/sandbox997235944/main.go:10 +0x120

送信側は、チャネルがバッファ付きだろうがなかろうが、データを送りきってからcloseすれば良いわけです。
close するタイミングと、受信側でcloseされたと判断されるタイミングに時差があるので、結果的には直感的ですが、ちょっと戸惑う挙動かと思います。
あまり言及している記事がなかった記憶があるので、知っているとproducer-consumer パターンの実装の時に役立ちます。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away