中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

golang中select語句怎么使用

發布時間:2022-09-23 14:54:50 來源:億速云 閱讀:179 作者:iii 欄目:開發技術

這篇文章主要介紹“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占用過高的問題;

1.先舉個簡單例子

先創建兩個信道,并在 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 就結束,所以輸出如下

golang中select語句怎么使用

2. 避免造成死鎖

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 的錯誤,就像下面這樣子。

golang中select語句怎么使用

1.解決這個問題的方法有兩種

一個是,養成好習慣,在 select 的時候,也寫好 default 分支代碼,盡管你 default 下沒有寫任何代碼。

golang中select語句怎么使用

 另一個是,讓其中某一個信道可以接收到數據

golang中select語句怎么使用

3. select 隨機性

之前學過 switch 的時候,知道了 switch 里的 case 是順序執行的,但在 select 里卻不是。

通過下面這個例子的執行結果就可以看出

golang中select語句怎么使用

4. select 的超時

當 case 里的信道始終沒有接收到數據時,而且也沒有 default 語句時,select 整體就會阻塞,但是有時我們并不希望 select 一直阻塞下去,這時候就可以手動設置一個超時時間。

golang中select語句怎么使用

5. 讀取/寫入都可以

上面例子里的 case,好像都只從信道中讀取數據,但實際上,select 里的 case 表達式只要求你是對信道的操作即可,不管你是往信道寫入數據,還是從信道讀出數據。

golang中select語句怎么使用

golang中select語句怎么使用

關于“golang中select語句怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

霍州市| 海盐县| 秦皇岛市| 兴安盟| 舞阳县| 咸丰县| 长葛市| 乌拉特前旗| 三门峡市| 莱芜市| 蓬溪县| 黑河市| 新疆| 尉犁县| 额济纳旗| 威信县| 清水县| 平南县| 乐至县| 固原市| 措勤县| 双牌县| 定安县| 布尔津县| 娱乐| 邯郸县| 扎囊县| 平邑县| 手游| 蓝山县| 亳州市| 灵寿县| 南岸区| 睢宁县| 永川市| 涞水县| 紫金县| 和政县| 昆山市| 鄢陵县| 县级市|