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

Go語言使用select監(jiān)聽多個channel的示例詳解

 更新時間:2025年08月03日 08:18:24   作者:程序員愛釣魚  
本文將聚焦 Go 并發(fā)中的一個強力工具,select,這篇文章將通過實際案例學(xué)習(xí)如何優(yōu)雅地監(jiān)聽多個 Channel,實現(xiàn)多任務(wù)處理、超時控制和非阻塞通信等并發(fā)技巧

一、前言:為什么要使用select

在 Go 的并發(fā)編程中,channel 是協(xié)程間通信的核心工具。但當你需要同時從多個 Channel 中接收數(shù)據(jù),或者在特定時間內(nèi)做出響應(yīng),select 就派上了大用場。

它類似于網(wǎng)絡(luò)編程中的 select/poll/epoll,用于監(jiān)聽多個 IO 操作的就緒狀態(tài),只不過這里的 IO 是 Channel 的讀寫操作。

二、實戰(zhàn)目標

我們將構(gòu)建一個并發(fā)任務(wù)監(jiān)聽系統(tǒng),實現(xiàn)以下目標:

  • 啟動多個任務(wù)(Goroutine),分別向不同的 Channel 寫入結(jié)果
  • 使用 select 監(jiān)聽多個 Channel,響應(yīng)哪個就處理哪個
  • 實現(xiàn)超時處理
  • 實現(xiàn) Channel 關(guān)閉退出機制

三、案例代碼:監(jiān)聽兩個任務(wù)結(jié)果和超時

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func task(name string, delay time.Duration, ch chan<- string) {
    time.Sleep(delay)
    ch <- fmt.Sprintf("任務(wù) %s 完成(耗時 %v)", name, delay)
}

func main() {
    rand.Seed(time.Now().UnixNano())

    task1Ch := make(chan string)
    task2Ch := make(chan string)

    // 啟動兩個任務(wù)
    go task("A", time.Duration(rand.Intn(2000))*time.Millisecond, task1Ch)
    go task("B", time.Duration(rand.Intn(2000))*time.Millisecond, task2Ch)

    // 使用 select 監(jiān)聽兩個任務(wù)完成情況
    timeout := time.After(2 * time.Second) // 超時設(shè)置

    for i := 0; i < 2; i++ {
        select {
        case res := <-task1Ch:
            fmt.Println("[監(jiān)聽] 收到任務(wù)1結(jié)果:", res)
        case res := <-task2Ch:
            fmt.Println("[監(jiān)聽] 收到任務(wù)2結(jié)果:", res)
        case <-timeout:
            fmt.Println("[監(jiān)聽] 等待超時!")
            return
        }
    }

    fmt.Println("主程序退出。")
}

四、運行示例

一次運行輸出:

[監(jiān)聽] 收到任務(wù)2結(jié)果: 任務(wù) B 完成(耗時 1.379s)
[監(jiān)聽] 收到任務(wù)1結(jié)果: 任務(wù) A 完成(耗時 1.962s)
主程序退出。

另一次運行(任務(wù)沒完成):

[監(jiān)聽] 等待超時!

五、重點解析:Go 中的select

1.select的行為特性

隨機選擇一個可用的 case 執(zhí)行(如果多個都可讀)

如果沒有任何 case 準備好,則阻塞,除非有 default

可以結(jié)合 time.After 實現(xiàn)超時控制

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

timeout := time.After(2 * time.Second)

這是 Go 提供的標準庫能力,會在 2 秒后向 timeout 這個只讀通道發(fā)送一個時間值,結(jié)合 select 使用非常方便。

3. 非阻塞通道監(jiān)聽(可選)

select {
case msg := <-ch:
    fmt.Println("收到消息:", msg)
default:
    fmt.Println("沒有消息,非阻塞處理")
}

六、延伸應(yīng)用場景

select 與 Channel 聯(lián)合使用,可以應(yīng)用于非常多的高并發(fā)場景:

場景用法說明
多任務(wù)結(jié)果優(yōu)先處理誰先完成就處理誰
多個服務(wù)節(jié)點返回最快結(jié)果服務(wù)冗余設(shè)計中的快速返回策略
實現(xiàn)“心跳檢測”或“任務(wù)超時”每個協(xié)程都有監(jiān)聽超時 Channel,任務(wù)不響應(yīng)就退出
限制任務(wù)處理時間(防止卡死)結(jié)合 context.WithTimeout() 更可靠

七、完整示例:結(jié)合for-select實現(xiàn)循環(huán)監(jiān)聽

func main() {
    dataCh := make(chan string)
    quitCh := make(chan bool)

    // 模擬異步數(shù)據(jù)流
    go func() {
        for i := 0; i < 5; i++ {
            dataCh <- fmt.Sprintf("數(shù)據(jù)包 #%d", i)
            time.Sleep(time.Millisecond * 500)
        }
        quitCh <- true
    }()

    for {
        select {
        case msg := <-dataCh:
            fmt.Println("接收數(shù)據(jù):", msg)
        case <-quitCh:
            fmt.Println("任務(wù)結(jié)束,退出監(jiān)聽循環(huán)")
            return
        case <-time.After(1 * time.Second):
            fmt.Println("1秒無數(shù)據(jù),超時處理...")
        }
    }
}

八、總結(jié)

通過本案例你學(xué)會了:

  • 如何使用 select 同時監(jiān)聽多個 Channel
  • 如何實現(xiàn)超時機制(time.After
  • 如何在主線程中等待異步任務(wù)完成
  • 如何構(gòu)建可擴展的并發(fā)通信模型

select 是 Go 并發(fā)編程的核心工具之一,它讓我們能夠優(yōu)雅地處理多路異步事件,是構(gòu)建高性能系統(tǒng)的利器。

到此這篇關(guān)于Go語言使用select監(jiān)聽多個channel的示例詳解的文章就介紹到這了,更多相關(guān)Go select監(jiān)聽hannel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang編寫自定義IP限流中間件的方法詳解

    Golang編寫自定義IP限流中間件的方法詳解

    這篇文章給大家詳細的介紹了Golang編寫自定義IP限流中間件的方法,文章通過代碼實例介紹的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-09-09
  • GO字符串練習(xí)題實例代碼

    GO字符串練習(xí)題實例代碼

    字符串在Go語言中是一個不可變的字節(jié)序列,通常用來表示文本,這篇文章主要介紹了GO字符串練習(xí)題的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2026-03-03
  • Golang使用Gin框架實現(xiàn)http分塊傳輸

    Golang使用Gin框架實現(xiàn)http分塊傳輸

    這篇文章主要為大家詳細介紹了Golang中如何使用Gin框架實現(xiàn)http分塊傳輸功能,文中的示例代碼講解詳細,具有一定的學(xué)習(xí)價值,需要的可以參考一下
    2023-05-05
  • Go語言獲取文件的名稱、前綴、后綴

    Go語言獲取文件的名稱、前綴、后綴

    這篇文章主要介紹了Go語言獲取文件的名稱、前綴、后綴,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • gin自定義中間件解決requestBody不可重復(fù)讀問題(最新推薦)

    gin自定義中間件解決requestBody不可重復(fù)讀問題(最新推薦)

    這篇文章主要介紹了gin自定義中間件解決requestBody不可重復(fù)讀問題,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Go Time庫中時間和日期相關(guān)的操作方法整理

    Go Time庫中時間和日期相關(guān)的操作方法整理

    這篇文章主要為大家整理了Go語言中的time庫,包括時間、日期和時區(qū)等相關(guān)概念及使用方法,希望通過掌握這些知識,大家可以更好地處理時間、日期和時區(qū)相關(guān)的問題
    2023-08-08
  • Go中標準庫fmt包的使用小結(jié)

    Go中標準庫fmt包的使用小結(jié)

    fmt包是Go語言處理輸入輸出的核心庫,提供Print/Scan系列函數(shù)及多樣格式化動詞(如%v、%d、%s等),支持字符串格式化、掃描、自定義輸出格式及錯誤處理,廣泛用于數(shù)據(jù)格式化與輸出控制,下面就來詳細的介紹一下
    2025-09-09
  • Go?語言范圍Range的基本用法實戰(zhàn)指南

    Go?語言范圍Range的基本用法實戰(zhàn)指南

    range是Go語言中一個非常強大的功能,可以用來遍歷數(shù)組、切片、映射、通道和字符串,這篇文章給大家介紹Go語言范圍Range的基本用法實戰(zhàn)指南,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • 深入分析Golang Server源碼實現(xiàn)過程

    深入分析Golang Server源碼實現(xiàn)過程

    這篇文章深入介紹了Golang Server源碼實現(xiàn)過程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • Go使用httptest包進行高效HTTP測試的流程步驟

    Go使用httptest包進行高效HTTP測試的流程步驟

    本文主要介紹了Go語言中`httptest`包的使用,該包通過內(nèi)存級HTTP通信解決了傳統(tǒng)測試方法的三大痛點,文章詳細解析了`httptest`包的核心組件,包括測試服務(wù)器和響應(yīng)記錄器,并提供了基礎(chǔ)使用模式、進階使用技巧和配置參數(shù)詳解,需要的朋友可以參考下
    2025-05-05

最新評論

侯马市| 遵化市| 双辽市| 克拉玛依市| 万盛区| 罗田县| 云霄县| 河津市| 镶黄旗| 乌兰察布市| 雷山县| 新巴尔虎右旗| 襄樊市| 合水县| 潮州市| 苏尼特左旗| 绥芬河市| 连山| 江永县| 军事| 巴南区| 陵水| 华坪县| 高清| 安新县| 湟源县| 东丰县| 沽源县| 自贡市| 三河市| 启东市| 博罗县| 大城县| 涟源市| 色达县| 思南县| 大宁县| 西乌珠穆沁旗| 凤阳县| 星子县| 辰溪县|