通道缓冲区比Go中的预期值多一个

时间:2017-06-13 23:18:54

标签: go channel

我认为Go中的通道默认只保留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

表示通道一次保存2个值。指定像这样的缓冲区大小

c := make(chan int, 0)

什么都不做。我能用它做任何方式只能保持1,值,而不是2?

2 个答案:

答案 0 :(得分:3)

  

表示通道一次保存2个值。

不是这样的。这就是代码的执行方式:

  1. goroutine阻止通道上的读取
  2. 第二个goroutine写入通道并继续执行
  3. 第二次goroutine在第二次写入尝试时阻止 ,因为没有人正在阅读
  4. main goroutine继续执行,打印读取的数字
  5. goroutine读取了另一个号码,因为有人写信给
  6. goroutine在下次阅读时打印读取的数字和块
  7. 第二个goroutine继续执行步骤 2。
  8. 没有缓冲区,只是并发。

答案 1 :(得分:0)

package main

import (
    "log"
)

func main() {
    seq := make(chan bool)
    for i := range numGen(6, seq) {
        <-seq
        log.Println("taking from channel", i)
    }
}

func numGen(num int, seq chan bool) chan int {
    c := make(chan int)
    go func() {
        for i := 0; i < num; i++ {
            c <- i
            log.Println("passing to channel", i)
            seq <- true // 要保证顺序,这里发送一个信号量。
        }
        close(c)
    }()

    return c
}