最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang中select語句的簡單實例

 更新時間:2022年06月29日 11:56:39   作者:燕雙鷹...  
Go的select語句是一種僅能用于channl發(fā)送和接收消息的專用語句,此語句運行期間是阻塞的,下面這篇文章主要給大家介紹了關于golang中select語句的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

前言

在golang語言中,select語句 就是用來監(jiān)聽和channel有關的IO操作,當IO操作發(fā)生時,觸發(fā)相應的case動作。有了 select語句,可以實現(xiàn) main主線程 與 goroutine線程 之間的互動。

select {
    case <-ch1 :     // 檢測有沒有數(shù)據(jù)可讀
        // 一旦成功讀取到數(shù)據(jù),則進行該case處理語句
    case ch2 <- 1 :  // 檢測有沒有數(shù)據(jù)可寫
        // 一旦成功向ch2寫入數(shù)據(jù),則進行該case處理語句
    default:
        // 如果以上都沒有符合條件,那么進入default處理流程
}

注意事項:

  • select語句 只能用于channel信道的IO操作,每個case都必須是一個信道。
  • 如果不設置 default條件,當沒有IO操作發(fā)生時,select語句就會一直阻塞;
  • 如果有一個或多個IO操作發(fā)生時,Go運行時會隨機選擇一個case執(zhí)行,但此時將無法保證執(zhí)行順序;
  • 對于case語句,如果存在信道值為nil的讀寫操作,則該分支將被忽略,可以理解為相當于從select語句中刪除了這個case;
  • 對于空的 select語句,會引起死鎖;
  • 對于在 for中的select語句,不能添加 default,否則會引起cpu占用過高的問題;

1.先舉個簡單例子

先創(chuàng)建兩個信道,并在 select 前往 c2 發(fā)送數(shù)據(jù)

package main
 
import (
	"fmt"
)
 
//go的通道選擇器 讓你可以同時等待多個通道操作。go協(xié)程和通道以及選擇器的結合是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 表達式,只要有一個信道有接收到數(shù)據(jù),那么 select 就結束,所以輸出如下

2. 避免造成死鎖

select 在執(zhí)行過程中,必須命中其中的某一分支。

如果在遍歷完所有的 case 后,若沒有命中(命中:也許這樣描述不太準確,我本意是想說可以執(zhí)行信道的操作語句)任何一個 case 表達式,就會進入 default 里的代碼分支。

package main
 
import (
	"fmt"
)
 
//go的通道選擇器 讓你可以同時等待多個通道操作。go協(xié)程和通道以及選擇器的結合是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.解決這個問題的方法有兩種

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

 另一個是,讓其中某一個信道可以接收到數(shù)據(jù)

3. select 隨機性

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

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

4. select 的超時

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

5. 讀取/寫入都可以

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

6. 總結一下

select 與 switch 原理很相似,但它的使用場景更特殊,學習了本篇文章,你需要知道如下幾點區(qū)別:

  1. select 只能用于 channel 的操作(寫入/讀出),而 switch 則更通用一些;
  2. select 的 case 是隨機的,而 switch 里的 case 是順序執(zhí)行;
  3. select 要注意避免出現(xiàn)死鎖,同時也可以自行實現(xiàn)超時機制;
  4. select 里沒有類似 switch 里的 fallthrough 的用法;
  5. select 不能像 switch 一樣接函數(shù)或其他表達式。

到此這篇關于golang中select語句的文章就介紹到這了,更多相關go中select語句內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go語言開發(fā)區(qū)塊鏈只需180行代碼(推薦)

    Go語言開發(fā)區(qū)塊鏈只需180行代碼(推薦)

    這篇文章主要介紹了Go語言開發(fā)區(qū)塊鏈只需180行代碼,文章中將不會涉及工作量證明算法(PoW)以及權益證明算法(PoS)這類的共識算法。需要的朋友可以參考下
    2018-05-05
  • 如何利用Golang寫出高并發(fā)代碼詳解

    如何利用Golang寫出高并發(fā)代碼詳解

    今天領導問起為什么用Golang,同事回答語法簡單,語言新,支持高并發(fā)。那高并發(fā)到底如何實現(xiàn),下面這篇文章主要給大家介紹了關于如何利用Golang寫出高并發(fā)代碼的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-09-09
  • 用Go語言標準庫實現(xiàn)Web服務之項目介紹

    用Go語言標準庫實現(xiàn)Web服務之項目介紹

    從本節(jié)開始將從后端到前端一步一步實現(xiàn)一個Go語言Web服務,后端除了MySQL驅動,全部使用Go語言標準庫來實現(xiàn)一個小型項目,本篇將簡單的介紹一下項目開發(fā)要準備的流程,感興趣的同學可以閱讀一下
    2023-05-05
  • Golang實踐筆錄之讀取yaml配置文件

    Golang實踐筆錄之讀取yaml配置文件

    YAML是YAML?Ain't?a?Markup?Language的縮寫,YAML不是一種標記語言,相比JSON格式的方便,這篇文章主要給大家介紹了關于Golang實踐筆錄之讀取yaml配置文件的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • Go?Excelize?API源碼閱讀Close及NewSheet方法示例解析

    Go?Excelize?API源碼閱讀Close及NewSheet方法示例解析

    這篇文章主要為大家介紹了Go?Excelize?API源碼閱讀Close及NewSheet方法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Go?語言進階單元測試示例詳解

    Go?語言進階單元測試示例詳解

    這篇文章主要為大家介紹了Go?語言進階單元測試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • 全面解析Go語言中crypto/sha1庫

    全面解析Go語言中crypto/sha1庫

    crypto/sha1在Go語言標準庫中是一個強大且實用的工具,適用于多種應用場景,本文就詳細的介紹了Go語言中crypto/sha1庫,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • 深入解析Golang中JSON的編碼與解碼

    深入解析Golang中JSON的編碼與解碼

    隨著互聯(lián)網的快速發(fā)展和數(shù)據(jù)交換的廣泛應用,各種數(shù)據(jù)格式的處理成為軟件開發(fā)中的關鍵問題,本文將介紹?Golang?中?JSON?編碼與解碼的相關知識,幫助大家了解其基本原理和高效應用,需要的可以收藏一下
    2023-05-05
  • Go?for-range?的?value值地址每次都一樣的原因解析

    Go?for-range?的?value值地址每次都一樣的原因解析

    循環(huán)語句是一種常用的控制結構,在?Go?語言中,除了?for?關鍵字以外,還有一個?range?關鍵字,可以使用?for-range?循環(huán)迭代數(shù)組、切片、字符串、map?和?channel?這些數(shù)據(jù)類型,這篇文章主要介紹了Go?for-range?的?value值地址每次都一樣的原因解析,需要的朋友可以參考下
    2023-05-05
  • Go語言基礎go fmt命令使用示例詳解

    Go語言基礎go fmt命令使用示例詳解

    這篇文章主要為大家介紹了Go語言基礎go fmt命令的使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-11-11

最新評論

象山县| 灵璧县| 四子王旗| 三亚市| 玉树县| 平和县| 维西| 奉化市| 乃东县| 舞阳县| 盈江县| 靖宇县| 泉州市| 武胜县| 日土县| 贡觉县| 临夏县| 新绛县| 三明市| 隆化县| 高雄市| 临夏县| 临潭县| 高唐县| 金坛市| 普洱| 澄迈县| 开封市| 卢湾区| 舒兰市| 西宁市| 东乡县| 宣化县| 应城市| 张北县| 南阳市| 图木舒克市| 观塘区| 茌平县| 阳高县| 新巴尔虎左旗|