GO語言網(wǎng)絡(luò)編程(并發(fā)編程)select
1、select
1.1.1 select多路復(fù)用
在某些場景下我們需要同時從多個通道接收數(shù)據(jù)。通道在接收數(shù)據(jù)時,如果沒有數(shù)據(jù)可以接收將會發(fā)生阻塞。你也許會寫出如下代碼使用遍歷的方式來實現(xiàn):
for{
// 嘗試從ch1接收值
data, ok := <-ch1
// 嘗試從ch2接收值
data, ok := <-ch2
…
}
這種方式雖然可以實現(xiàn)從多個通道接收值的需求,但是運行性能會差很多。為了應(yīng)對這種場景,Go內(nèi)置了select關(guān)鍵字,可以同時響應(yīng)多個通道的操作。文章來源:http://www.zghlxwxcb.cn/news/detail-708878.html
select的使用類似于switch語句,它有一系列case分支和一個默認(rèn)的分支。每個case會對應(yīng)一個通道的通信(接收或發(fā)送)過程。select會一直等待,直到某個case的通信操作完成時,就會執(zhí)行case分支對應(yīng)的語句。具體格式如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-708878.html
select {
case <-chan1:
// 如果chan1成功讀到數(shù)據(jù),則進行該case處理語句
case chan2 <- 1:
// 如果成功向chan2寫入數(shù)據(jù),則進行該case處理語句
default:
// 如果上面都沒有成功,則進入default處理流程
}
- select可以同時監(jiān)聽一個或多個channel,直到其中一個channel ready
package main
import (
"fmt"
"time"
)
func test1(ch chan string) {
time.Sleep(time.Second * 5)
ch <- "test1"
}
func test2(ch chan string) {
time.Sleep(time.Second * 2)
ch <- "test2"
}
func main() {
// 2個管道
output1 := make(chan string)
output2 := make(chan string)
// 跑2個子協(xié)程,寫數(shù)據(jù)
go test1(output1)
go test2(output2)
// 用select監(jiān)控
select {
case s1 := <-output1:
fmt.Println("s1=", s1)
case s2 := <-output2:
fmt.Println("s2=", s2)
}
}
- 如果多個channel同時ready,則隨機選擇一個執(zhí)行
package main
import (
"fmt"
)
func main() {
// 創(chuàng)建2個管道
int_chan := make(chan int, 1)
string_chan := make(chan string, 1)
go func() {
//time.Sleep(2 * time.Second)
int_chan <- 1
}()
go func() {
string_chan <- "hello"
}()
select {
case value := <-int_chan:
fmt.Println("int:", value)
case value := <-string_chan:
fmt.Println("string:", value)
}
fmt.Println("main結(jié)束")
}
- 可以用于判斷管道是否存滿
package main
import (
"fmt"
"time"
)
// 判斷管道有沒有存滿
func main() {
// 創(chuàng)建管道
output1 := make(chan string, 10)
// 子協(xié)程寫數(shù)據(jù)
go write(output1)
// 取數(shù)據(jù)
for s := range output1 {
fmt.Println("res:", s)
time.Sleep(time.Second)
}
}
func write(ch chan string) {
for {
select {
// 寫數(shù)據(jù)
case ch <- "hello":
fmt.Println("write hello")
default:
fmt.Println("channel full")
}
time.Sleep(time.Millisecond * 500)
}
}
到了這里,關(guān)于GO語言網(wǎng)絡(luò)編程(并發(fā)編程)select的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!