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

通道缓冲区在Go中比预期值多取一个值,go,channel,Go,Channel,我认为Go中的通道在默认情况下只保留1个值,除非指定了缓冲区大小。我读过。但当我运行这个: 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 < nu

我认为Go中的通道在默认情况下只保留1个值,除非指定了缓冲区大小。我读过。但当我运行这个:

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
}
这表明通道一次保持2个值。指定这样的缓冲区大小

c := make(chan int, 0)
什么也不做。我能不能让它只保存1,值,而不是2

这表明通道一次保持2个值

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

  • maingoroutine阻塞通道上的读取
  • 第二个goroutine写入通道并继续执行
  • 第二个goroutine在第二次写入尝试时阻塞,因为没有人在读取
  • maingoroutine继续执行,打印读取的编号
  • maingoroutine读取另一个数字,因为有人正在给它写信
  • maingoroutine在下次读取时打印读取的编号和块
  • 第二个goroutine继续在步骤2执行。
  • 没有缓冲区,只有并发性

    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
    }
    
    这表明通道一次保持2个值

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

  • maingoroutine阻塞通道上的读取
  • 第二个goroutine写入通道并继续执行
  • 第二个goroutine在第二次写入尝试时阻塞,因为没有人在读取
  • maingoroutine继续执行,打印读取的编号
  • maingoroutine读取另一个数字,因为有人正在给它写信
  • maingoroutine在下次读取时打印读取的编号和块
  • 第二个goroutine继续在步骤2执行。
  • 没有缓冲区,只有并发。

    package main
    
    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
    }
    
    进口( “日志” ) func main(){ 序号:=制造(陈波) 对于i:=范围numGen(6,序号){
    主程序包
    进口(
    “日志”
    )
    func main(){
    序号:=制造(陈波)
    对于i:=范围numGen(6,序号){
    
    显示频道一次保存2个值。
    没有。您的频道甚至没有保存一个值。请详细说明
    显示频道一次保存2个值。
    没有。您的频道甚至没有保存一个值。请详细说明。第二个go例程中的forloop保持不变正在执行,所以第二个print语句执行,并在通道通过时停止。谢谢。我明白了。第二个go例程中的forloop继续执行,所以第二个print语句执行,并在通道通过时停止。谢谢