Golang学习笔记14:并发编程之select
select
Linux很早就引入的函数,用来实现异步非阻塞的一种方式。
Go语言直接在语言级别支持select关键字,用于处理异步IO问题。
select{
case <- chan1: //如果chan1成功读到数据,则进行该case处理语句
case chan2 <- 1: //如果成功向chan2写入数据,则进行该case处理语句
default: //如果上面都没有成功,则进入default处理流程
}
首先体验一下select的用法:
//select.go
package main
import (
"fmt"
)
func main(){
ch := make(chan int)
select {
case <- ch: //没人写入,阻塞在这里
fmt.Print("come to read ch!")
default: //如果前面的case都没有准备好,默认走到default
fmt.Print("come to default!")
}
}
输出结果:
come to default!
创建一个匿名函数协程
//select.go
package main
import (
"fmt"
"time"
)
func main(){
ch := make(chan int)
go func(ch chan int){ //匿名函数
ch <- 1
}(ch)
time.Sleep(time.Second) //让主协程睡一下 让他主动去执行上面匿名函数的协程
//不然到select的时候ch还是不能读
select {
case <- ch: //没人写入,阻塞在这里
fmt.Print("come to read ch!")
default: //如果前面的case都没有准备好,默认走到default
fmt.Print("come to default!")
}
}
输出结果:
come to read ch!
一个超时控制的经典实现
timeout := make(chan bool,1)
go func(){
time.Sleep(1e9) //等待1秒钟
timeout <- true
}()
//然后我们把timeout这个channel利用起来
select{
case <- ch: //从ch中读取到数据
case <- timeout: //一直没有从ch中读取到数据,但从timeout中读取到了数据
}
实现例子如下:
package main
import (
"fmt"
"time"
)
func main(){
ch := make(chan int)
timeout := make(chan int , 1)
go func(){
time.Sleep(time.Second)
timeout <- 1
}()
go func(ch chan int){
ch <- 1
}(ch)
//time.Sleep(time.Second) //让主协程睡一下 让他主动去执行上面匿名函数的协程
//不然到select的时候ch还是不能读
select {
case <- ch: //没人写入,阻塞在这里
fmt.Print("come to read ch!")
case <- timeout: //如果前面的case都没有准备好,默认走到default
fmt.Print("come to timeout!")
}
}
一秒钟的超时控制,如果没有ch写入,也会进入case <- timeout。
time.After方法进行超时控制
没有运用协程。
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
select {
case <-ch:
fmt.Print("come to read ch!")
case <-time.After(time.Second):
fmt.Print("come to timeout!")
}
fmt.Print("end of code!")
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 赛 の 任意门!
评论
ValineGitalk