欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言中select使用詳解

 更新時間:2025年05月14日 11:02:04   作者:gopher.guo  
這篇文章主要介紹了Go語言中select使用的相關資料,select是Go語言中用于多路channel操作的控制結構,可以監(jiān)聽多個channel的發(fā)送與接收操作,當其中某一個可以進行時就執(zhí)行對應的語句,從而實現(xiàn)非阻塞并發(fā)通信,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

什么是 select?

select 是 Go 中用于 多路 channel 操作 的控制結構,它可以監(jiān)聽多個 channel 的發(fā)送與接收操作,當其中某一個可以進行時就執(zhí)行對應的語句,從而實現(xiàn)非阻塞并發(fā)通信。

基本語法

select {
case val := <-ch1:
    // ch1 可讀時執(zhí)行
case ch2 <- 100:
    // ch2 可寫時執(zhí)行
default:
    // 所有 channel 都阻塞時執(zhí)行(可選)
}
  • 每個 case 必須是 發(fā)送(ch <- val)或接收(val := <-ch)

  • 只會執(zhí)行一個可操作的 case(如果多個都可以隨機挑一個)

  • 如果都阻塞,且沒有 default,select 會阻塞等待

  • 如果包含 default,它會立即執(zhí)行,哪怕其他 case 可能之后才可操作

使用場景舉例

1. 監(jiān)聽多個 channel 的數(shù)據(jù)

select {
case msg1 := <-ch1:
    fmt.Println("收到 ch1:", msg1)
case msg2 := <-ch2:
    fmt.Println("收到 ch2:", msg2)
}

2. 實現(xiàn)超時機制

select {
case msg := <-ch:
    fmt.Println("收到:", msg)
case <-time.After(2 * time.Second):
    fmt.Println("超時")
}

time.After 返回一個 channel,在指定時間后變?yōu)榭勺x,實現(xiàn)優(yōu)雅的 timeout。

3. 非阻塞發(fā)送或接收(default 分支)

select {
case ch <- data:
    fmt.Println("發(fā)送成功")
default:
    fmt.Println("channel 滿,放棄發(fā)送")
}

4. 檢測通道是否關閉

select {
case v, ok := <-ch:
    if !ok {
        fmt.Println("通道關閉")
    } else {
        fmt.Println("收到:", v)
    }
}

select 的行為特點

行為描述
隨機調度多個 case 同時可用時隨機選擇一個執(zhí)行(防止饑餓)
阻塞等待所有 case 阻塞時,select 自身也阻塞
default 分支所有 case 阻塞時立即執(zhí)行,避免阻塞
只選一個同時滿足多個時只執(zhí)行其中一個

與 goroutine 配合:生產(chǎn)者/消費者模型

func producer(ch chan int) {
    for i := 0; i < 5; i++ {
        ch <- i
    }
    close(ch)
}
?
func consumer(ch chan int, done chan struct{}) {
    for {
        select {
        case val, ok := <-ch:
            if !ok {
                done <- struct{}{}
                return
            }
            fmt.Println("消費:", val)
        }
    }
}

select + for:常見循環(huán)寫法

for {
    select {
    case msg := <-ch:
        fmt.Println("收到:", msg)
    case <-time.After(5 * time.Second):
        fmt.Println("超時退出")
        return
    }
}

select 常見陷阱

陷阱描述
忘記 default 導致阻塞如果所有 case 阻塞,select 也阻塞
無限阻塞select 中所有 channel 永遠不會可用
channel 已關閉向已關閉通道寫入會 panic,應特別小心
超時誤用使用 time.After() 時,不要在循環(huán)里頻繁創(chuàng)建新 channel,否則內存泄漏

?? 解決建議:使用 time.NewTimer,并復用 timer。

實戰(zhàn)建議

建議原因
用 select 實現(xiàn)超時控制比較優(yōu)雅且非阻塞
select + default 實現(xiàn)非阻塞通信避免 goroutine 卡死
用 select + context.Done() 控制退出在大型系統(tǒng)中更適合

例子:context 控制退出(推薦生產(chǎn)使用)

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
?
ch := make(chan int)
?
go func() {
    time.Sleep(2 * time.Second)
    ch <- 42
}()
?
select {
case <-ctx.Done():
    fmt.Println("操作取消/超時:", ctx.Err())
case val := <-ch:
    fmt.Println("接收到數(shù)據(jù):", val)
}

總結

維度說明
功能實現(xiàn) channel 的多路復用監(jiān)聽
優(yōu)點非阻塞、高效、優(yōu)雅處理通信控制
結合time.After、context、default 最佳組合
場景goroutine 退出、任務超時、并發(fā)協(xié)程間通信控制等

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

相關文章

  • golang常用庫之配置文件解析庫-viper使用詳解

    golang常用庫之配置文件解析庫-viper使用詳解

    viper 配置管理解析庫,是由大神 Steve Francia 開發(fā),他在google領導著 golang 的產(chǎn)品開發(fā),他也是 gohugo.io 的創(chuàng)始人之一,命令行解析庫 cobra 開發(fā)者,這篇文章主要介紹了golang常用庫之配置文件解析庫-viper使用詳解,需要的朋友可以參考下
    2020-10-10
  • GO語言函數(shù)(func)的聲明與使用詳解

    GO語言函數(shù)(func)的聲明與使用詳解

    這篇文章主要介紹了GO函數(shù)(func)的聲明與使用,包括了GO語言函數(shù)聲明與使用,GO語言遞歸函數(shù),GO語言內置函數(shù),GO語言函數(shù)defer應用,GO語言函數(shù)可變長度參數(shù)需要的朋友可以參考下
    2022-12-12
  • Go語言如何實現(xiàn)線程安全的Map

    Go語言如何實現(xiàn)線程安全的Map

    Go語言內置的map雖然高效,但并不是線程安全的,若在多線程環(huán)境中直接操作map,可能會引發(fā)并發(fā)寫入的錯誤,下面我們就來看看如何實現(xiàn)線程安全的Map吧
    2024-11-11
  • golang模擬TCP粘包和拆包

    golang模擬TCP粘包和拆包

    粘包是指在發(fā)送多個小的數(shù)據(jù)包時,接收端會將這些數(shù)據(jù)包合并成一個數(shù)據(jù)包接收,拆包是指發(fā)送的數(shù)據(jù)包在傳輸過程中被分割成多個小包,下面我們來看看go如何模擬TCP粘包和拆包吧
    2024-12-12
  • Go語言學習網(wǎng)絡編程與Http教程示例

    Go語言學習網(wǎng)絡編程與Http教程示例

    這篇文章主要為大家介紹了Go語言學習網(wǎng)絡編程與Http教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Go中使用操作符進行數(shù)學運算的示例代碼

    Go中使用操作符進行數(shù)學運算的示例代碼

    在編程中有效地執(zhí)行數(shù)學運算是一項需要開發(fā)的重要技能,本文主要介紹了Go中使用操作符進行數(shù)學運算的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • Go語言Http?Server框架實現(xiàn)一個簡單的httpServer

    Go語言Http?Server框架實現(xiàn)一個簡單的httpServer

    這篇文章主要為大家介紹了Go語言Http?Server框架實現(xiàn)一個簡單的httpServer抽象,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Go 中燒腦的接口及空接口

    Go 中燒腦的接口及空接口

    在Go語言的實際編程中,幾乎所有的數(shù)據(jù)結構都圍繞接口展開,接口是Go語言中所有數(shù)據(jù)結構的核心,這篇文章主要介紹了Go 中燒腦的接口,需要的朋友可以參考下
    2024-02-02
  • Golang WaitGroup實現(xiàn)原理解析

    Golang WaitGroup實現(xiàn)原理解析

    WaitGroup是Golang并發(fā)的兩種方式之一,一個是Channel,另一個是WaitGroup,下面這篇文章主要給大家介紹了關于golang基礎之waitgroup用法以及使用要點的相關資料,需要的朋友可以參考下
    2023-02-02
  • 解讀rand.Seed(time.Now().UnixNano())的作用及說明

    解讀rand.Seed(time.Now().UnixNano())的作用及說明

    這篇文章主要介紹了關于rand.Seed(time.Now().UnixNano())的作用及說明,具有很好的參考價值,希望對大家有所幫助。
    2023-03-03

最新評論