前言
作为一门现代语言,go语言实现了对并发的原生支持。如果现在要对channel进行控制,从语言层面上来说,select语句是必不可少的部分,今天我们就对select语句的行为和使用做一些讨论。
select的使用示例
为了便于理解,我们首先给出一个代码片段:
select {
case v1 := <-c1:
fmt.Printf("received %v from c1\n", v1)
case v2 := <-c2:
fmt.Printf("received %v from c2\n", v1)
case c3 <- 23:
fmt.Printf("sent %v to c3\n", 23)
default:
fmt.Printf("no one was ready to communicate\n")
}
上面这段代码中,select语句中有四个case子语句,前两个receive操作,第三个send操作,最后一个是默认操作。代码执行到select时,case语句会按照源代码的顺序来评估(评估这个词,感觉不是很专业??),并且只是评估一次,评估的结果会出现下面四种情况:
- 除default外,如果只有一个case语句评估通过,那么就执行这个case里面的语句
- 除default外,如果有多个case语句评估通过,那么就通过伪随机的方式随机选一个(随机的方式是怎么样的?)
- 如果default外的case语句都没有通过评估,那么执行defalut里的语句
- 如果没有default,那么代码块会被阻塞,直到有一个case通过评估,否则会一直阻塞
设置超时时间
我们希望设置某个模块的超时时间,下面是简单的demo:
func main() {
var c chan int
timeout := time.After(5 * time.Second)
for{
select {
case s := <-c:
fmt.Println(s)
case <-timeout:
fmt.Println("You talk too much.")
return
}
}
}