go - channel 缓冲区比 Go 中的预期多取一个值

标签 go channel

我认为 Go 中的 channel 默认只保存 1 个值,除非指定缓冲区大小。我读到 here .但是当我运行这个时:

func main (){
    for i := range numGen(6) {
        log.Println("taking from channel", i)
    }
}

func numGen(num int) chan int {
    c := make(chan string)
    go func() {
        for i := 0; i < num; i++ {
            log.Println("passing to channel", i)
            c <- i
        }
        close(c)
    }
    return c
}

我的输出是:

2017/06/13 18:09:08 passing to channel 0
2017/06/13 18:09:08 passing to channel 1
2017/06/13 18:09:08 taking from channel 0
2017/06/13 18:09:08 taking from channel 1
2017/06/13 18:09:08 passing to channel 2
2017/06/13 18:09:08 passing to channel 3
2017/06/13 18:09:08 taking from channel 2
2017/06/13 18:09:08 taking from channel 3
2017/06/13 18:09:08 passing to channel 4
2017/06/13 18:09:08 passing to channel 5
2017/06/13 18:09:08 taking from channel 4
2017/06/13 18:09:08 taking from channel 5

这表明 channel 一次保存 2 个值。像这样指定缓冲区大小

c := make(chan int, 0)

什么都不做。有什么方法可以让它只包含 1,值,而不是 2?

最佳答案

which shows that the channel is holding 2 values at a time.

事实并非如此。代码是这样执行的:

  1. ma​​in goroutine block 在 channel 上读取
  2. 第二个 goroutine 写入 channel 并继续执行
  3. 第二个 goroutine 在第二次写入尝试时阻塞,因为没有人在读取
  4. ma​​in goroutine 继续执行,打印读取的数字
  5. ma​​in goroutine 读取另一个数字,因为有人正在写入它
  6. ma​​in goroutine 打印读取次数并在下一次读取时阻塞
  7. 第二个 goroutine 在 2 步继续执行。

没有缓冲区,只有并发。

关于go - channel 缓冲区比 Go 中的预期多取一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44533029/

相关文章:

function - 关闭不返回所需的输出

go - Golang 的 Homebrew 公式

go - golang 中的无类型 channel

go - 如何在同一循环内向 channel 发送值或从 channel 接收值?

php - Telegram bot 不响应 channel 中的消息?

golang所有goroutines都睡着了 - 死锁

golang中的JSON解码

去redis连接db1

go - 获取 labix.org/v2/mgo 错误远程服务器意外关闭连接

java - Jsch "exec"执行长时间运行命令后 channel 不会自动关闭