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

Golang關鍵字select的常用用法總結

 更新時間:2023年10月26日 09:58:56   作者:林欣快滾去學習  
這篇文章主要為大家詳細介紹了golang中select關鍵字的常用用法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一、Select解決什么問題

在Golang中,兩個協(xié)程之間通信Channel(圖一),在接受協(xié)程中通過代碼表示即為<ch;如果協(xié)程需要監(jiān)聽多個Channel,只要有其中一個滿足條件,就執(zhí)行相應的邏輯(圖二),這種select的應用場景之一,代碼如下:

func TestSelect(t *testing.T) {
    ch1 := make(chan int, 1)
    ch2 := make(chan int , 1)

    select {
        case <-ch1:
        fmt.Println("ch1")
        case <-ch2:
        fmt.Println("ch2")
        default:
        }
}

上述代碼,創(chuàng)建兩個通道,通過select監(jiān)聽協(xié)程是否有數(shù)據(jù),如果有打印相應的值,如果沒有通過default結束程序運行;

二、Select常用用法

循環(huán)阻塞監(jiān)測

func TestLoopSelect(t *testing.T) {
    ch1 := make(chan int, 1)
    ch2 := make(chan int, 1)

    go func() {
        // 每隔1s發(fā)送一條消息到channel中
        for range time.Tick(1 * time.Second) {
            ch1 <- 1
        }
    }()

    for {
        select {
            case <-ch1:
            fmt.Println("ch1")
            case <-ch2:
            fmt.Println("ch2")
        }
    }
}

這種寫法特別常見,起一個協(xié)程,阻塞循環(huán)監(jiān)聽多個channel,如果有數(shù)據(jù)執(zhí)行對應的操作。比如說

// go-zero/core/discov/internal/registry.go
func (c *cluster) watchStream(cli EtcdClient, key string, rev int64) bool {
    var rch clientv3.WatchChan
    if rev != 0 {
        rch = cli.Watch(clientv3.WithRequireLeader(c.context(cli)), makeKeyPrefix(key), clientv3.WithPrefix(),
                      clientv3.WithRev(rev+1))
    } else {
        rch = cli.Watch(clientv3.WithRequireLeader(c.context(cli)), makeKeyPrefix(key), clientv3.WithPrefix())
    }

    for {
        select {
            case wresp, ok := <-rch:
        	...
            c.handleWatchEvents(key, wresp.Events)
            case <-c.done:
            return true
        }
    }
}

上述代碼,通過for + select阻塞循環(huán)監(jiān)測注冊中心數(shù)據(jù)是否有變換,有變化的話,針對變化類型,執(zhí)行對應邏輯;

非阻塞監(jiān)控

func TestSelect(t *testing.T) {
    ch1 := make(chan int, 1)
    ch2 := make(chan int , 1)

    select {
        case <-ch1:
        fmt.Println("ch1")
        case <-ch2:
        fmt.Println("ch2")
        default:
        }
}

這段代碼的意思是,程序執(zhí)行到select,就檢查一下channel里面是否有數(shù)據(jù),有就處理,沒有就退出;在grpc-go中,

// grpc-go/clientconn.go
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) {
	cc := &ClientConn{
		target: target,
		conns:  make(map[*addrConn]struct{}),
		dopts:  defaultDialOptions(),
		czData: new(channelzData),
	}

	defer func() {
		select {
		case <-ctx.Done():
			switch {
			case ctx.Err() == err:
				conn = nil
			case err == nil || !cc.dopts.returnLastError:
				conn, err = nil, ctx.Err()
			default:
				conn, err = nil, fmt.Errorf("%v: %v", ctx.Err(), err)
			}
		default:
		}
	}()

	if cc.dopts.scChan != nil {
		// Blocking wait for the initial service config.
		select {
		case sc, ok := <-cc.dopts.scChan:
			if ok {
				cc.sc = &sc
				cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc})
			}
		case <-ctx.Done():
			return nil, ctx.Err()
		}
	}

}

上述代碼中,有兩個地方用到select,一個地方是非阻塞,檢查contex是否被取消;另外一個是阻塞等待;

三、select原理

如果想了解select的實現(xiàn),可以閱讀runtime.selectgo代碼。它主要包含三部分:

首先,檢查一下是否有準備就緒的channel(多個channel就緒,隨機選擇一個),如果有,就執(zhí)行;

其次,將當前goroutine包裝成sudog,掛載到對應的channel上;

最后,如果channel中數(shù)據(jù)準備就緒,喚醒該協(xié)程繼續(xù)執(zhí)行第一步邏輯;

【注】源碼細節(jié),感興趣并且有需求可以深入了解,但是不要陷入源碼的怪圈中;

總結

本文主要講述下面三部分內容:

  • 從Go源碼開發(fā)者的角度考慮,為什么需要select?
  • 介紹了select常用的兩種寫法,一種是非阻塞的,一種是阻塞的,以及開源項目如何使用它們;
  • 介紹了select的基本實現(xiàn);

以上就是Golang關鍵字select的常用用法總結的詳細內容,更多關于go select的資料請關注腳本之家其它相關文章!

相關文章

  • Go源碼分析之預分配slice內存

    Go源碼分析之預分配slice內存

    這篇文章主要從Go語言源碼帶大家分析一下預分配slice內存的相關知識,文中的示例代碼簡潔易懂,對我們深入了解go有一定的幫助,需要的可以學習一下
    2023-08-08
  • Go 請求兔子識別接口實現(xiàn)流程示例詳解

    Go 請求兔子識別接口實現(xiàn)流程示例詳解

    這篇文章主要為大家介紹了Go 請求兔子識別接口實現(xiàn)流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • golang?使用sort.slice包實現(xiàn)對象list排序

    golang?使用sort.slice包實現(xiàn)對象list排序

    這篇文章主要介紹了golang?使用sort.slice包實現(xiàn)對象list排序,對比sort跟slice兩種排序的使用方式區(qū)別展開內容,需要的小伙伴可以參考一下
    2022-03-03
  • 詳解Golang如何比較兩個slice是否相等

    詳解Golang如何比較兩個slice是否相等

    開發(fā)中常會遇到需要比較兩個slice包含的元素是否完全相等的情況,我們通常會通過兩種方法去比較切片是否相等。這里通過幾個示例來看一下這兩種方法,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助
    2022-11-11
  • go語言題解LeetCode1128等價多米諾骨牌對的數(shù)量

    go語言題解LeetCode1128等價多米諾骨牌對的數(shù)量

    這篇文章主要為大家介紹了go語言題解LeetCode1128等價多米諾骨牌對的數(shù)量示例詳解,
    2022-12-12
  • 關于golang中map使用的幾點注意事項總結(強烈推薦!)

    關于golang中map使用的幾點注意事項總結(強烈推薦!)

    map是一種無序的基于key-value的數(shù)據(jù)結構,Go語言中的map是引用類型,必須初始化才能使用,下面這篇文章主要給大家介紹了關于golang中map使用的幾點注意事項,需要的朋友可以參考下
    2023-01-01
  • golang中GOPROXY如何設置

    golang中GOPROXY如何設置

    在Go語言開發(fā)中,合理設置 GOPROXY 環(huán)境變量可以顯著提升依賴包的下載速度和穩(wěn)定性,針對高級場景,可以配置多代理冗余、禁止代理訪問特定包或關閉校驗和驗證,下面就來詳細的介紹一下
    2026-02-02
  • Golang配置解析神器go?viper使用詳解

    Golang配置解析神器go?viper使用詳解

    viper是一個很完善的Go項目配置解決方案,很多著名的開源項目都在使用,比如Hugo,Docker都使用了該庫,使用viper可以讓我們專注于自己的項目代碼,而不用自己寫那些配置解析代碼,本文給大家介紹Golang配置解析神器go?viper使用,感興趣的朋友一起看看吧
    2022-05-05
  • golang實現(xiàn)nacos獲取配置和服務注冊-支持集群詳解

    golang實現(xiàn)nacos獲取配置和服務注冊-支持集群詳解

    文章介紹了如何在Go語言中使用Nacos獲取配置和服務注冊,支持集群初始化,客戶端結構體中的IpAddresses可以配置多個地址,新客戶端支持集群配置,文章還討論了如何將Nacos獲取到的配置與項目中的Viper無縫對接,以便進行Viper的正常操作
    2025-11-11
  • Go語言實現(xiàn)的排列組合問題實例(n個數(shù)中取m個)

    Go語言實現(xiàn)的排列組合問題實例(n個數(shù)中取m個)

    這篇文章主要介紹了Go語言實現(xiàn)的排列組合問題,結合實例形式分析了Go語言實現(xiàn)排列組合數(shù)學運算的原理與具體操作技巧,需要的朋友可以參考下
    2017-02-02

最新評論

永新县| 洱源县| 鄢陵县| 旬阳县| 岳普湖县| 新闻| 堆龙德庆县| 梁平县| 沈丘县| 民勤县| 桐柏县| 六盘水市| 新源县| 黄石市| 巴塘县| 景谷| 龙井市| 通化县| 宁都县| 正宁县| 塔城市| 惠水县| 朝阳区| 应用必备| 富川| 安义县| 义乌市| 沧州市| 错那县| 莲花县| 延边| 白朗县| 高要市| 海林市| 宁强县| 嘉鱼县| 鸡泽县| 驻马店市| 高陵县| 车险| 上虞市|