### 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
- 多線程:通道思路
- 多線程爬蟲:快代理