Select 语句使用
[TOC]
1. select 介绍
select 介绍select语句用于从多个发送方/接收方的channel中选取需要接受的数据。select语句是阻塞的,直到一个case满足条件,或者定义了default语句。语法与switch相似。
使用select的主要场景可以是一个多服务器的服务。每一个服务器都提供相同的服务,并且具有重复的数据库,对于用户的一个请求,多个服务器都可以做出回应但是最终用户只接收到一个返回。因为负载以及网络延迟等,不同服务器做出反应的时间可能不同,此时选取反应最快的。以达到集群的最优用户体验。
func server1(ch chan string) {
time.Sleep(1 * time.Second)
ch <- "from server 1"
}
func server2(ch chan string) {
time.Sleep(3 * time.Second)
ch <- "from server 2"
}
func main() {
out1 := make(chan string)
out2 := make(chan string)
go server1(out1)
go server2(out2)
select {
case s1 := <-out1:
fmt.Println(s1)
case s2 := <-out2:
fmt.Println(s2)
//default:
// fmt.Println(nil)
}
}
//去掉注释,则返回 nil1.1 default case
default case可以避免系统陷入阻塞。当没有一个case就绪时,默认执行default case。
在processroutine中等待10.5s,在mainroutine中,每一秒检查一次是否有可以接受的channel数据。前10s都没有,所以输出default。接收到process的数据后,程序退出.
1.2 死锁以及default case
可以使用default case来避免死锁。例如对于一个一直等待读数据的channel,可以添加default解除死锁.
即使是一个没有经过初始化,为nil的channel,也可以解除其死锁。
对于一个cases为空的select语句,会造成死锁,引起一直阻塞
1.3 随机选择
当一个select语句中的多个cases都满足条件,那么这些语句被随机选择执行。
Last updated
Was this helpful?