示例1:
select + default实现非阻塞式的获取
select:哪个case语句执行得快,就执行哪个case语句;如果没有case语句执行,就执行default
在本示例中,由于c1和c2都为nil,所以两个case语句不执行,而是执行default语句。
package main
import "fmt"
func main() {
var c1, c2 chan int // c1 and c2 = nil
for {
select {
case n := <-c1: // 当c1为nil时,该case语句不会执行
fmt.Println("Received from c1:", n)
case n:= <-c2: // 当c2为nil时,该case语句不会执行
fmt.Println("Received from c2:", n)
default:
fmt.Println("No value received") // No value received
}
}
}
示例2:
func generator() chan int {
out := make(chan int)
go func() {
i := 0
for {
time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) // sleep 0-1500ms
out <- i
i++
}
}()
return out
}
func worker(id int, c chan int) {
for n := range c {
time.Sleep(time.Second)
fmt.Printf("Worker %d received %d\n", id, n)
}
}
func createWorker(id int) chan<- int {
c := make(chan int)
go worker(id, c)
return c
}
func main() {
var c1, c2 = generator(), generator()
var worker = createWorker(0)
var values []int
for {
var activeWorker chan<- int // activeWorker = nil
var activeValue int
if len(values) > 0 {
activeWorker = worker
activeValue = values[0]
}
select {
case n := <-c1:
values = append(values, n)
case n := <-c2:
values = append(values, n)
case activeWorker <- activeValue: // 当activeWorker为nil时,该case语句不会执行
values = values[1:]
}
}
}
示例3:计时器的使用
time.After(x) -> 返回一个channel,x时间后会往该channel中发送一个值
time.Tick(x) -> 返回一个channel,每隔x时间往该channel里送一个值
func generator() chan int {
out := make(chan int)
go func() {
i := 0
for {
time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) // sleep 0-1500ms
out <- i
i++
}
}()
return out
}
func worker(id int, c chan int) {
for n := range c {
time.Sleep(time.Second)
fmt.Printf("Worker %d received %d\n", id, n)
}
}
func createWorker(id int) chan<- int {
c := make(chan int)
go worker(id, c)
return c
}
func main() {
var c1, c2 = generator(), generator()
var worker = createWorker(0)
var values []int
tm := time.After(10 * time.Second)
tick := time.Tick(time.Second)
for {
var activeWorker chan<- int // activeWorker = nil
var activeValue int
if len(values) > 0 {
activeWorker = worker
activeValue = values[0]
}
select {
case n := <-c1:
values = append(values, n)
case n := <-c2:
values = append(values, n)
case activeWorker <- activeValue: // 当activeWorker为nil时,该case语句不会执行
values = values[1:]
case <-time.After(800 * time.Millisecond): // 如果800ms后还没获得数据,则打印"timeout"
fmt.Println("timeout")
case <-tick: // 每秒钟查看一次队列长度
fmt.Println("queue len =", len(values))
case <-tm: // 10秒钟后退出程序
fmt.Println("bye")
return
}
}
}