### select作用
select关键词用于监听通道数据的流动,用法类似于switch
```
select {
case <-chan1:
//如果成功读取到chan1的数据,就执行该case语句
case <-chan2:
//如果成功读取到chan2的数据,就执行该case语句
...
default:
//如果上面case都没有执行成功,则执行该default语句
}
```
```
package main
import (
"fmt"
"time"
)
func main() {
// 创建一个通道
ch := make(chan int)
go func() {
for i := 0; i < 3; i++ {
// i发送到通道
ch <- i
}
}()
for {
// 监听通道的数据
select {
// msg是读取通道的内容
case msg := <-ch:
fmt.Println(msg)
default:
//如果没有case可以执行 就会堵塞 一直执行default。进程会从select后恢复执行
// 如果没有 default语句,那么就会一直堵塞,直到有通道可以进行下去
time.Sleep(time.Second)
}
fmt.Println("到这会恢复")
}
}
```
### 超时
有时候协程出现堵塞,为避免长时间堵塞,可以使用select来实现堵塞机制
```
package main
import (
"fmt"
"time"
)
func main() {
// 创建一个通道传递 for循环的i
ch := make(chan int)
// 接收bool
done := make(chan bool)
go func() {
for {
select {
// val取出通道ch里面的值
case val := <-ch:
fmt.Println(val)
case <-time.After(time.Second * 3):
fmt.Println("已经超时3秒")
// true发送给通道done
done <- true
}
}
}()
for i := 0; i < 10; i++ {
// i发送个通道ch
ch <- i
}
// 取通道 done 里面的值
//<-done
fmt.Println(<-done)
fmt.Println("程序终止")
}
```
### 死锁
流出无流入,流入无流出,都会造成死锁
```
package main
func main() {
ch := make(chan int)
<-ch //堵塞main gotoutine,通信ch被锁
}
```
```
package main
func main() {
select {}
}
```
```
fatal error: all goroutines are asleep - deadlock!
```
- 安装开发环境
- 安装开发环境
- 安装详细教程
- 引入包
- Go语言基础
- 基本变量与数据类型
- 变量
- 数据类型
- 指针
- 字符串
- 代码总结
- 常量与运算符
- 常量
- 运算符
- 流程控制
- if判断
- for循环
- switch分支
- goto跳转
- 斐波那契数列
- Go语言内置容器
- 数组
- 切片
- 映射
- 函数
- 函数(上)
- 函数(中)
- 函数(下)
- 小节
- 包管理
- 结构体
- 结构体(上)
- 结构体(中)
- 结构体(下)
- 小节
- 错误处理
- 错误处理
- 宕机
- 错误应用
- 小节
- 文件操作
- 获取目录
- 创建和删除目录
- 文件基本操作(上)
- 文件基本操作(中)
- 文件基本操作(下)
- 处理JSON文件
- 接口与类型
- 接口的创建与实现
- 接口赋值
- 接口嵌入
- 空接口
- 类型断言(1)
- 类型断言(2)
- 小节
- 并发与通道
- goroutine协程
- runtime包
- 通道channel
- 单向通道channel
- select
- 线程同步
- 多线程的深入学习
- http编程
- http简介
- Client和Request
- get请求
- post请求
- 模块函数方法
- 模块
- fmt库,模块
- 项目练习
- 爬虫:高三网
- 爬虫:快代理
- 爬虫:快代理2
- 多线程:通道思路
- 多线程爬虫:快代理