0

I thought that channels in Go only hold 1 value by default unless the buffer size if specified. I read that here. But when I run this:

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
}

my output is:

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

which shows that the channel is holding 2 values at a time. Specifying a buffer size like this

c := make(chan int, 0)

does nothing. Any way I could make it only hold 1, value, not 2?

Mauricio
  • 419
  • 4
  • 14

2 Answers2

3

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

Thats not the case. This is how the code executes:

  1. The main goroutine blocks on a read on the channel
  2. The second goroutine writes to the channel and continues executing.
  3. The second goroutine blocks at the second write attempt because noone is reading
  4. The main goroutine continues executing, prints the read number
  5. The main goroutine reads another number since someone is writing to it
  6. The main goroutine prints the read number and blocks on the next read
  7. The second goroutine continues executing at step 2.

There is no buffer, just concurrency.

tkausl
  • 13,686
  • 2
  • 33
  • 50
  • I see. The forloop inside the second go routine keeps executing, so the second print statement executes, and stops at the channel-passing. Thank you for that – Mauricio Jun 13 '17 at 23:36
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
}
0x7ff
  • 11
  • 2