Skip to content

Instantly share code, notes, and snippets.

@balaa
Forked from t9md/go-tour-select.go
Created January 20, 2020 09:54
Show Gist options
  • Select an option

  • Save balaa/d6ec2f9a948bbe015048d30caf5c06c9 to your computer and use it in GitHub Desktop.

Select an option

Save balaa/d6ec2f9a948bbe015048d30caf5c06c9 to your computer and use it in GitHub Desktop.
Go's Channel and select {} illustrated
package main
/*
Channel and select {} illustrated by t9md
===========================================================
sample program to understand goroutine communication via channel.
based on go-tour's example
https://tour.golang.org/concurrency/5
*/
import "fmt"
func fibonacci(out, quit chan int) {
x, y := 0, 1
for {
select {
case out <- x: // if out-ch is available for write(means out-ch's buffer is not full), send next fib number x
x, y = y, x+y
case <-quit: // if some data come to quit-ch, then break inifinite loop by return.
fmt.Println("quit")
return
}
}
}
func main() {
/*
main() start
+-- main() --+
| |
| |
| |
| |
+------------+
*/
out := make(chan int)
quit := make(chan int)
/*
two channel (out, quit) created
+-- main() --+
| |--------------
| | out<int>
| |--------------
| |--------------
| | quit<int>
| |--------------
+------------+
*/
// Create anonymous func() and immediately execute as goroutine.
// This function iterate 10 times of (read fib number from out-ch and Println).
// After that, send `0` to quit-ch to notify other fibonacci() to break inifinit loop.
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-out) // pop data from chan-out 10 times
}
quit <- 0 // then send 0 to quit
}()
/*
+--- main () -------------+ +--- goroutine: func() ---------------+
| | | |
| | ------------ | for i := 0; i < 10; i++ { | *1
| | out<int> ====> fmt.Println(<-out) //(*1) | Blocking here for now.
| | ------------ | } | since no data come from out-ch.
| | | | First data will come after fibonacci() start
| | ------------ | |
| | quit<int> <== 0 quit <- 0 | *2
| | ------------ | | Send 0 to quit-ch for the purpose of break
| | | | inifinit loop of fibonacci()
| | | |
+-------------------------+ +--------------------------------------+
*/
fibonacci(out, quit)
/*
fibonacci() start, this fibonacci() function inifinitely generate fibonacci
numbers, unless some data is sent to channel 'quit'
+---anonymous func() in main()--+ +-- fibonacci()---------+
| for i := 0; i < 10; i++ { |------------------- | select { |
| t.Println(<-out) <====== out<int> <== x | case out <- x: |
| } |------------------- | x, y = x, x+y |
| | | |
| | | |
| |------------------- | |
| quit <- 0 0 =======> quit<int> =======> case <- quit: |
| |------------------- | fmt.Println("quit) |
| | | return |
| | | } |
+-------------------------------+ +-----------------------+
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment