Question

http://play.golang.org/p/uRHG-Th_2P

I am having hard time understanding the concept of channel

package main

import (
  "fmt"
)

func Fibonacci(limit int, chnvar chan int) {
  x, y := 0, 1
  for i := 0; i < limit; i++ {
    chnvar <- x
    x, y = y, x+y
  }
  close(chnvar)

  v, ok := <-chnvar
  fmt.Println(v, ok)
}


func main() {
  chn := make(chan int, 10)
  go Fibonacci(cap(chn), chn)
  for elem := range chn {
    fmt.Printf("%v ", elem)
  }
}
//1 1 2 3 5 8 13 21 34 

1) How do I get false value from the line

v, ok := <-chnvar

It says false if there are no more values to get. and also false if the channel is closed. But in this case, the channel is closed but(?) still get the true value.

And if I take out the close, it panics.

How and why it returns true here?

2) The line

 go Fibonacci(cap(chn), chn)

also runs without goroutine. What is the difference? Just matter of performance.

Thanks in advance

Was it helpful?

Solution

  1. Your Fibonacci function stuffs 10 values into the channel (which has a buffer of 10 values), and then closes it. Assuming the v, ok <- chnvar statement executes before the main goroutine reads everything out of the channel (very likely, but not guaranteed), there will be a value to read so ok will be true.

    If you remove the close call, the for loop in the main goroutine will eventually empty the channel's buffer and block waiting for more data. Since there is no other goroutine active to write to the channel, the runtime detects this as a deadlock.

  2. Your sample program runs with Fibonacci called directly (not as a goroutine) because the channel it writes to is buffered, and it never overruns the buffer. Therefore it can complete without blocking and allows execution to continue to the rest of the main function.

    If the channel was not buffered, or you wrote more values than would fit in the buffer, then Fibonacci would block waiting for some other goroutine to read something from the channel.

OTHER TIPS

1)

The Go specification states for channel receive operations (my emphasis):

x, ok := <-ch

The value of ok is true if the value received was delivered by a successful send operation to the channel, or false if it is a zero value generated because the channel is closed and empty.

That is, because the buffered channel is not empty and you have successfully received a value (0), ok will be true. You won't receive false until the channel has been emptied.

2)

By running the Fibonacci(cap(chn), chn) in it's own Go routine, main can start receiving and processing (printing out) out values while the Fibonacci function is still feeding new values to the channel.
In your case, this probably never happens since the function will have filled up the buffer and completed before main gets a chance to process anything.

If it would not be running in a Go routine, Fibonacci would first need to produce all the values before they can be processed further by main.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top