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

Go?select使用與底層原理講解

 更新時間:2022年07月31日 14:34:28   作者:樹獺叔叔???????  
這篇文章主要介紹了Go?select使用與底層原理講解,select是Go提供的IO多路復(fù)用機制,可以用多個cas同時監(jiān)聽多個channl的讀寫狀態(tài),相關(guān)內(nèi)容需要的朋友可以參考一下

1. select的使用

select 是 Go 提供的 IO 多路復(fù)用機制,可以用多個 case 同時監(jiān)聽多個 channl 的讀寫狀態(tài):

  • case: 可以監(jiān)聽 channl 的讀寫信號
  • default:聲明默認操作,有該字段的 select 不會阻塞
select {
case chan <-:
    // TODO
case <- chan:
    // TODO
default:
    // TODO
}

2. 底層原理

  • 每一個 case 對應(yīng)的 channl 都會被封裝到一個結(jié)構(gòu)體中;
  • 當?shù)谝淮螆?zhí)行到 select 時,會鎖住所有的 channl 并且,打亂 case 結(jié)構(gòu)體的順序;
  • 按照打亂的順序遍歷,如果有就緒的信號,就直接走對應(yīng) case 的代碼段,之后跳出 select;
  • 如果沒有就緒的代碼段,但是有 default 字段,那就走 default 的代碼段,之后跳出 select;
  • 如果沒有 default,那就將當前 goroutine 加入所有 channl 的對應(yīng)等待隊列;
  • 當某一個等待隊列就緒時,再次鎖住所有的 channl,遍歷一遍,將所有等待隊列中的 goroutine 取出,之后執(zhí)行就緒的代碼段,跳出select。

3. 數(shù)據(jù)結(jié)構(gòu)

每一個 case 對應(yīng)的數(shù)據(jù)結(jié)構(gòu)如下:

type scase struct {
    c           *hchan         // chan
    elem        unsafe.Pointer // 讀或者寫的緩沖區(qū)地址
    kind        uint16   //case語句的類型,是default、傳值寫數(shù)據(jù)(channel <-) 還是  取值讀數(shù)據(jù)(<- channel)
    pc          uintptr // race pc (for race detector / msan)
    releasetime int64
}

4. 幾種常見 case

學(xué)習了 select 的使用與原理,我們就能更輕松地分辨不同情況下的輸出情況了。

case 1

package main

import (
  "fmt"
  "time"
)

func main() {
  chan1 := make(chan int)
  chan2 := make(chan int)
  go func() {
    chan1 <- 1
    time.Sleep(5 * time.Second)
  }()
  go func() {
    chan2 <- 1
    time.Sleep(5 * time.Second)
  }()
  select {
    case <- chan1:
      fmt.Println("chan1")
    case <- chan2:
      fmt.Println("chan2")
    default:
      fmt.Println("default")
  }
}

三種輸出都有可能。

case2

package main

import (
  "fmt"
  "time"
)
func main() {
  chan1 := make(chan int)
  chan2 := make(chan int)
  
  select {
    case <- chan1:
      fmt.Println("chan1")
    case <- chan2:
      fmt.Println("chan2")
  }
  fmt.Println("main exit.")
}

上述程序會一直阻塞。

case3

package main

import (
  "fmt"
)

func main() {
  chan1 := make(chan int)
  chan2 := make(chan int)
  
  go func() {
    close(chan1)
  }()
  go func() {
    close(chan2)
  }()
  select {
    case <- chan1:
      fmt.Println("chan1")
    case <- chan2:
      fmt.Println("chan2")
  }
  fmt.Println("main exit.")
}

隨機執(zhí)行1或者2.

case4

package main

func main() {
  select {
  }
}

對于空的 select 語句,程序會被阻塞,確切的說是當前協(xié)程被阻塞,同時 Go 自帶死鎖檢測機制,當發(fā)現(xiàn)當前協(xié)程再也沒有機會被喚醒時,則會發(fā)生 panic。所以上述程序會 panic。

到此這篇關(guān)于Go select使用與底層原理講解的文章就介紹到這了,更多相關(guān)Go select使用 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Golang?Slice切片如何擴容的實現(xiàn)

    淺談Golang?Slice切片如何擴容的實現(xiàn)

    本文主要介紹了淺談Golang?Slice切片如何擴容的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • golang http使用踩過的坑與應(yīng)對方式

    golang http使用踩過的坑與應(yīng)對方式

    這篇文章主要介紹了golang http使用踩過的坑與應(yīng)對方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 詳解如何使用go-acme/lego實現(xiàn)自動簽發(fā)證書

    詳解如何使用go-acme/lego實現(xiàn)自動簽發(fā)證書

    這篇文章主要為大家詳細介紹了如何使用?go-acme/lego?的客戶端或庫完成證書的自動簽發(fā),文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習一下
    2024-03-03
  • Go微服務(wù)網(wǎng)關(guān)的實現(xiàn)

    Go微服務(wù)網(wǎng)關(guān)的實現(xiàn)

    本文主要介紹了Go微服務(wù)網(wǎng)關(guān)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2022-07-07
  • Go語言實現(xiàn)定時器的原理及使用詳解

    Go語言實現(xiàn)定時器的原理及使用詳解

    這篇文章主要為大家詳細介紹了Go語言實現(xiàn)定時器的兩種方法:一次性定時器(Timer)和周期性定時器(Ticker),感興趣的小伙伴可以跟隨小編一起學(xué)習一下
    2022-12-12
  • Go秒爬博客園100頁新聞

    Go秒爬博客園100頁新聞

    利用go語言的協(xié)程并發(fā)優(yōu)勢爬取網(wǎng)頁速度相當之快,博客園100頁新聞標題只需一秒即可全部爬取,跟著小編一起去看看如何實現(xiàn)的,希望大家可以從中受益
    2018-09-09
  • Golang實現(xiàn)定時任務(wù)的幾種方法小結(jié)

    Golang實現(xiàn)定時任務(wù)的幾種方法小結(jié)

    在 Golang 開發(fā)中,定時任務(wù)是常見的需求,本文將介紹幾種在 Golang 中實現(xiàn)定時任務(wù)的方法,包括 time 包的定時器、ticker,以及第三方庫 cron,并通過示例代碼展示它們的使用方式,需要的朋友可以參考下
    2024-01-01
  • gin?session中間件使用及源碼流程分析

    gin?session中間件使用及源碼流程分析

    這篇文章主要為大家介紹了gin?session中間件使用及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Golang監(jiān)聽日志文件并發(fā)送到kafka中

    Golang監(jiān)聽日志文件并發(fā)送到kafka中

    這篇文章主要介紹了Golang監(jiān)聽日志文件并發(fā)送到kafka中,日志收集項目的準備中,本文主要講的是利用golang的tail庫,監(jiān)聽日志文件的變動,將日志信息發(fā)送到kafka中?,需要的朋友可以參考一下
    2022-04-04
  • Golang多個域名的跨域資源共享的實現(xiàn)

    Golang多個域名的跨域資源共享的實現(xiàn)

    本文主要介紹了Golang多個域名的跨域資源共享的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2025-02-02

最新評論

兰考县| 西城区| 宁明县| 太和县| 双牌县| 无锡市| 固安县| 蚌埠市| 鄂尔多斯市| 湘西| 呼伦贝尔市| 伊通| 新干县| 报价| 通许县| 五常市| 临朐县| 大关县| 胶南市| 隆回县| 禹城市| 虹口区| 双峰县| 长泰县| 宾川县| 漠河县| 蓬安县| 余姚市| 思南县| 武宁县| 乌鲁木齐市| 涟源市| 乌兰浩特市| 冀州市| 峨眉山市| 南京市| 江陵县| 青州市| 丘北县| 赞皇县| 绥德县|