您現在的位置是:首頁 > 科技

Go語言select語句用法示例

曙光部落格2023-03-08 08:08:08【科技】

多個通道 Channel 中信息的發送和接受處理的專用的語句—select 語句。select 語句會阻塞,直到其中的一個發送/接收操作准備好。select 語句和 switch 語句有點相似,但 select 語句在被執行時會選擇執行其中的一個分支,且選擇分支的方法完全是不相同的。

ch1 = make(chan string)ch2 = make(chan string)ch1 <- "server1"ch2 <- "server1"select {case i := <- ch1:  fmt.Printf("從ch1讀取了數據%d", i)case j := <- ch2:  fmt.Printf("從ch2讀取了數據%d", i)default:  fmt.Printf("no action...", i)}

以上代碼中,每個 case 後都只針對某個通道的接收語句,這個和 switch 不同,也沒有 break。switch 語句右邊是一個switch 表達式,但 select 右邊是接大括號。

開始執行 select 語句時,所有跟在 case 關鍵字右邊的表達式都會被求值,求值的順序是自上而下,從左到右的。

使用場景

實現收發功能

select 是控制 channel 必不可少的部分,channel 的主要功能就是收發信息,基於此可以設計一個生產者消費者功能。生產者發送消息,消費者接受消息

func main(){// 生產數據,將數據寫入 channel   n1 := make(chan int)go func() {i := 0for {time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)n1 <- ii++}}()n2 := make(chan int)go func() {i := 0for {time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)n2 <- ii++}}()// 從 channel 中讀取到數據就輸出for {select {case n := <-n1:fmt.Printf("從ch1讀取了數據%d", n)case n := <-n2:fmt.Printf("從ch1讀取了數據%d", n)}}}

注意事項

select 只能用於 chan 的 IO 操作select 的 case 都是並行的,case 讀取到數據就執行,但是如果沒有讀取到且未設置 default 將導致阻塞盡量設置 default 避免沒有 IO 操作發生時,select 語句一直阻塞,直到某個 case 分支命中如果是空的 select 有可能會引起死鎖,所以在 select 執行過程中,必須命中某一 case 分支

select {}

防止阻塞還有一個方法:設置超時

文章評論

    共有條評論來說兩句吧...

    用戶名:

    驗證碼: