您好,登錄后才能下訂單哦!
這篇文章主要介紹“golang中select語句怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“golang中select語句怎么使用”文章能幫助大家解決問題。
在golang語言中,select語句 就是用來監聽和channel有關的IO操作,當IO操作發生時,觸發相應的case動作。有了 select語句,可以實現 main主線程 與 goroutine線程 之間的互動。
select { case <-ch2 : // 檢測有沒有數據可讀 // 一旦成功讀取到數據,則進行該case處理語句 case ch3 <- 1 : // 檢測有沒有數據可寫 // 一旦成功向ch3寫入數據,則進行該case處理語句 default: // 如果以上都沒有符合條件,那么進入default處理流程 }
注意事項:
select語句 只能用于channel信道的IO操作,每個case都必須是一個信道。
如果不設置 default條件,當沒有IO操作發生時,select語句就會一直阻塞;
如果有一個或多個IO操作發生時,Go運行時會隨機選擇一個case執行,但此時將無法保證執行順序;
對于case語句,如果存在信道值為nil的讀寫操作,則該分支將被忽略,可以理解為相當于從select語句中刪除了這個case;
對于空的 select語句,會引起死鎖;
對于在 for中的select語句,不能添加 default,否則會引起cpu占用過高的問題;
先創建兩個信道,并在 select 前往 c2 發送數據
package main import ( "fmt" ) //go的通道選擇器 讓你可以同時等待多個通道操作。go協程和通道以及選擇器的結合是go的一個強大特性。 func main() { // 在我們的例子中,我們將從兩個通道中選擇。 c1 := make(chan string, 1) c2 := make(chan string, 1) c2 <- "nihao" //go func() { // time.Sleep(time.Second * 1) // c1 <- "one" //}() // //go func() { // time.Sleep(time.Second * 2) // c2 <- "two" //}() //我們使用 `select` 關鍵字來同時等待這兩個值,并打印各自接收到的值。 //for i := 0; i < 2; i++ { select { case msg1 := <-c1: fmt.Println("received", msg1) case msg2 := <-c2: fmt.Println("received", msg2) default: fmt.Println("No data received") } //} }
在運行 select 時,會遍歷所有(如果有機會的話)的 case 表達式,只要有一個信道有接收到數據,那么 select 就結束,所以輸出如下
select 在執行過程中,必須命中其中的某一分支。
如果在遍歷完所有的 case 后,若沒有命中(命中:也許這樣描述不太準確,我本意是想說可以執行信道的操作語句)任何一個 case 表達式,就會進入 default 里的代碼分支。
package main import ( "fmt" ) //go的通道選擇器 讓你可以同時等待多個通道操作。go協程和通道以及選擇器的結合是go的一個強大特性。 func main() { // 在我們的例子中,我們將從兩個通道中選擇。 c1 := make(chan string, 1) c2 := make(chan string, 1) //c2 <- "nihao" //go func() { // time.Sleep(time.Second * 1) // c1 <- "one" //}() // //go func() { // time.Sleep(time.Second * 2) // c2 <- "two" //}() //我們使用 `select` 關鍵字來同時等待這兩個值,并打印各自接收到的值。 //for i := 0; i < 2; i++ { select { case msg1 := <-c1: fmt.Println("received", msg1) case msg2 := <-c2: fmt.Println("received", msg2) //default: // fmt.Println("No data received") //} } }
但如果你沒有寫 default 分支,select 就會阻塞,直到有某個 case 可以命中,而如果一直沒有命中,select 就會拋出 deadlock
的錯誤,就像下面這樣子。
1.解決這個問題的方法有兩種
一個是,養成好習慣,在 select 的時候,也寫好 default 分支代碼,盡管你 default 下沒有寫任何代碼。
另一個是,讓其中某一個信道可以接收到數據
之前學過 switch 的時候,知道了 switch 里的 case 是順序執行的,但在 select 里卻不是。
通過下面這個例子的執行結果就可以看出
當 case 里的信道始終沒有接收到數據時,而且也沒有 default 語句時,select 整體就會阻塞,但是有時我們并不希望 select 一直阻塞下去,這時候就可以手動設置一個超時時間。
上面例子里的 case,好像都只從信道中讀取數據,但實際上,select 里的 case 表達式只要求你是對信道的操作即可,不管你是往信道寫入數據,還是從信道讀出數據。
關于“golang中select語句怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。