Exercises
Channels
Modify the program you created in exercise to usechannels, in other words, the function called in the body should now bea goroutine and communication should happen via channels. You should notworry yourself on how the goroutine terminates.
There are a few annoying issues left if you resolve question 1 above. One ofthe problems is that the goroutine isn’t neatly cleaned up when
main.main()
exits. And worse, due to a race condition between the exit ofmain.main()
andmain.shower()
not all numbers are printed. It should print up until 9,but sometimes it prints only to 8. Adding a second quit-channel you canremedy both issues. Do this.
Answer
- A possible program is:
package main
import "fmt"
func main() {
ch := make(chan int)
go shower(ch)
for i := 0; i < 10; i++ {
ch <- i
}
}
func shower(c chan int) {
for {
j := <-c
fmt.Printf("%d\n", j)
}
}
We start in the usual way, then at line 6 we create a new channel of ints. In the next line we fire off the function shower
with the ch
variable as it argument, so that we may communicate with it. Next we start our for-loop (lines 8-10) and in the loop we send (with <-
) our number to the function (now a goroutine) shower
.
In the function shower
we wait (as this blocks) until we receive a number (line 15). Any received number is printed (line 16) and then continue the endless loop started on line 14.
- An answer is
package main
import "fmt"
func main() {
ch := make(chan int)
quit := make(chan bool)
go shower(ch, quit)
for i := 0; i < 10; i++ {
ch <- i
}
quit <- false // or true, does not matter
}
func shower(c chan int, quit chan bool) {
for {
select {
case j := <-c:
fmt.Printf("%d\n", j)
case <-quit:
break
}
}
}
On line 20 we read from the quit channel and we discard the value we read. We could have used q := <-quit
, but then we would have used the variable only once — which is illegal in Go. Another trick you might have pulled out of your hat may be: _ = <-quit
. This is valid in Go, but idomatic Go is the one given on line 20.
Fibonacci II
This is the same exercise as an earlier one inexercise. For completeness the complete question:
The Fibonacci sequence starts as follows: (1, 1, 2, 3, 5, 8, 13, \ldots)Or in mathematical terms:(x1 = 1; x_2 = 1; x_n = x{n-1} + > x_{n-2}\quad\forall n > 2).
Write a function that takes an
int
value and givesthat many terms of the Fibonacci sequence.
But now the twist: You must use channels.
Answer
The following program calculates the Fibonacci numbers using channels.
package main
import "fmt"
func dup3(in <-chan int) (<-chan int, <-chan int, <-chan int) {
a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2)
go func() {
for {
x := <-in
a <- x
b <- x
c <- x
}
}()
return a, b, c
}
func fib() <-chan int {
x := make(chan int, 2)
a, b, out := dup3(x)
go func() {
x <- 0
x <- 1
<-a
for {
x <- <-a+<-b
}
}()
return out
}
func main() {
x := fib()
for i := 0; i < 10; i++ {
fmt.Println(<-x)
}
}
// See sdh33b.blogspot.com/2009/12/fibonacci-in-go.html