go channel用法

介紹

channel 在 Go 中是一種專門用來在 goroutine 之間傳遞數據類型安全的管道

你可以把它理解成:

  • 多個 goroutine 之間的**“傳話筒”**,誰往通道里塞東西,另一個 goroutine 就能接收到。

Go 語言采用 CSP(Communicating Sequential Processes) 模型,也就是鼓勵:

💡 “不要通過共享內存來通信,而要通過通信來共享內存”

也就是通過 channel 來傳遞數據,而不是多個 goroutine 同時操作一份共享數據,這樣能減少復雜的鎖。

🧬 channel 的關鍵特性

? 類型化

通道是有類型的,比如 chan int 只能傳 int,chan string 只能傳 string。

? 同步

默認情況下,不緩沖通道是同步阻塞

  • 發送方(ch <- value)如果沒人接收,就等著。
  • 接收方(<- ch)如果沒人發送,也等著。

? 緩沖區可選

你也可以給通道設置緩沖區,比如 make(chan int, 10),這樣最多能存 10 個 int,不滿時發送方不會阻塞。

? 關閉通道

當通道關閉(close(ch))后再接收,不會再阻塞,而是返回對應類型的零值和一個標志。

🎨 實際用法場景

  • 任務分發:生產者 goroutine 往通道里傳任務,消費者 goroutine 從通道取任務。
  • 信號通知:用通道只傳遞空 struct 來通知某個 goroutine 開始或結束工作。
  • 并發控制:限制 goroutine 數量,比如用緩沖通道當作信號量。

go func()

go func() {channel <- "Hello, World!"
}()

這里啟動了一個新的 goroutine 來往通道中發送數據

go func() { … }() 相當于讓任務異步執行,也就是你說的 Python 里的 create_task() 或者 await 背后的任務調度

當無緩沖通道必須一手給一手拿,所以你必須用 goroutine 來讓另一個任務并行接收,否則就死鎖。

假設你去掉 go func(),直接寫成:

channel := make(chan string)
channel <- "Hello, World!" // 直接發送
msg := <-channel
fmt.Println(msg)

那么這一行 channel <- “Hello, World!” 會一直卡住,因為:

  • 這是無緩沖通道,必須同時有接收方(也就是 <- channel)在等著。
  • 但是程序還沒執行到接收方那一行,所以就死鎖了。

用 go func() 把發送操作放到后臺 goroutine 中,這樣主 goroutine 可以繼續執行接收邏輯,不再相互卡住。

換句話說:

  • goroutine A:負責發送
  • goroutine B:負責接收

如果沒有 goroutine,把發送和接收寫在一條順序執行流里,就造成死鎖。

? 所有 channel 都必須這樣寫嗎?

不必須,取決于場景:

  • 📌 如果你用緩沖通道,也就是:
ch := make(chan string, 1)
ch <- "Hello"
msg := <-ch
  • 有緩沖,所以發送完能直接存進去,不會阻塞,這時候也可以不用 goroutine。

? 📌 如果你的接收方先執行,比如:

ch := make(chan string)
go func() {msg := <- chfmt.Println(msg)
}()
ch <- "Hello"

無緩沖通道要求

發送和接收必須成對并發執行

也可以用緩沖通道,這樣中間能暫存數據,就不用 goroutine。

無緩沖通道 vs 緩沖通道

類別定義行為
無緩沖通道ch := make(chan string)必須一手交錢一手交貨(也就是發送時必須有接收方正在等著),否則發送方就堵住,不往下執行
有緩沖通道ch := make(chan string, N)通道內部有個緩沖區,當緩沖區沒滿時可以先把數據存起來,不需要接收方馬上接收,發送方能繼續往下走

🔍 為什么無緩沖通道單線程會卡?

無緩沖通道相當于是零容量隊列,你要往里面塞東西,但是根本沒有位置存,所以必須有人正在取,這時候才成對地完成操作。

你原來的例子:

channel := make(chan string) // 無緩沖通道
channel <- "Hello" // <=== 這里堵住了
msg := <-channel

為什么堵住?

因為這一行執行時:

  • 當前 goroutine 在這里卡住,等待另一個 goroutine 來接收數據。
  • 但是你下一行還沒執行,所以沒有接收者!于是永遠卡死。
  • 🧑?🤝?🧑 無緩沖通道:必須當場給對方(必須有接收者正在等)。
  • 📦 有緩沖通道:先放進快遞柜(緩沖區),接收方可以遲點取。

用 Python 類比一下也許更清楚:

  • 無緩沖通道就像你用 await queue.put(),但是沒有任何任務在取 → 任務永遠卡在那里。
  • goroutine 就像你用 create_task() 啟動另一個任務負責 queue.get(),那么 put() 就能順利執行完。

🔥 沒緩沖通道:必須有接收方同時存在,否則卡死,所以你要用 goroutine 來接收。

🔥 有緩沖通道:通道能先存東西,不必馬上接收,所以可以順利執行完發送,不用 goroutine。

普通 int 變量與 channel 的區別

對比點普通 int 變量chan int 通道
類型int 只存一個數字chan int 用來傳送數字給別人
用法num := 42 然后用 numch := make(chan int) 然后用 ch <- 42 傳數據
并發場景只在當前 goroutine能在多個 goroutine之間傳遞數據,不共享狀態
行為單純取值、賦值發送必須有接收方,不然 goroutine 會等著
目的存數據讓 goroutine 之間通信

🎯 相當于什么現實場景?

💡 想象你有兩個工人:

  1. 工人A(goroutine A)負責生產東西(例如生產一個數字)。
  2. 工人B(goroutine B)負責接收東西然后打印出來。

那么:

  • int num = 42 相當于是你自己手里拿著東西,沒給任何人。
  • channel <- 42 相當于是你把東西放上傳送帶,另一個工人能從傳送帶拿東西,這樣兩個人之間就實現協作啦。

你可以用共享變量,但是:

  • 要加鎖(防止讀寫沖突)。
  • 要自己控制什么時候生產、什么時候消費,不然很可能出錯。

用 channel 你就不用自己實現這些復雜邏輯,Go 會幫你:

? 發送數據時自動等待接收方。

? 接收數據時自動等待生產方。

? 并發安全,不用你加鎖。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/910535.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/910535.shtml
英文地址,請注明出處:http://en.pswp.cn/news/910535.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

openLayers切換基于高德、天地圖切換矢量、影像、地形圖層

1、需要先加載好地圖&#xff0c;具體點此鏈接 openLayers添加天地圖WMTS、XYZ瓦片服務圖層、高德地圖XYZ瓦片服務圖層-CSDN博客文章瀏覽閱讀31次。本文介紹了基于OpenLayers的地圖交互功能實現&#xff0c;主要包括以下內容&#xff1a; 地圖初始化&#xff1a;支持天地圖XYZ…

springMVC-15 異常處理

異常處理-基本介紹 基本介紹 1.Spring MVC通過HandlerExceptionResolver處理程序的異常&#xff0c;包括Handler映射、數據綁定以及目標方法執行時發生的異常。 2.主要處理Handler中用ExceptionHandler注解定義的方法。 3.ExceptionHandlerMethodResolver內部若找不到Excepti…

視頻匯聚EasyCVR平臺v3.7.2發布:新增全局搜索、播放器默認解碼方式等4大功能

EasyCVR視頻匯聚平臺帶著全新的v3.7.2版本重磅登場&#xff01;此次升級&#xff0c;絕非簡單的功能堆砌&#xff0c;而是從用戶體驗、操作效率以及系統性能等多維度進行的深度優化與革新&#xff0c;旨在為大家帶來更加強大、穩定且高效的視頻監控管理體驗。 一、全局功能搜索…

三、kubectl使用詳解

三、kubectl使用詳解 文章目錄 三、kubectl使用詳解1、常用基礎命令1.1 Kubectl命令格式1.2 查詢一個資源1.3 創建一個資源1.4 修改一個資源1.5 刪除一個資源1.6 其他 2、K8s隔離機制Namespace&#xff08;命名空間作用及使用&#xff09;2.1 什么是命名空間2.2 命名空間主要作…

JVM內存模型詳解

JVM內存模型詳解 Java虛擬機(JVM)內存模型是理解Java程序運行機制的核心&#xff0c;它定義了程序運行時數據的組織方式和訪問規則。與Java內存模型(JMM)關注并發不同&#xff0c;JVM內存模型主要描述運行時數據區的結構和功能。 一、JVM內存模型概述 JVM內存模型將運行時數…

《對話式 AI 白皮書》共創者招募

在 AI Agent 技術不斷演變的當下&#xff0c;共創一本不斷演變的對話式 AI 白皮書&#xff0c;共同探索人機對話的新紀元。無論你是開發者、技術專家、生態伙伴還是創業者&#xff0c;都期待你的加入。 項目地址&#xff1a;https://github.com/RTE-Dev/book_era_convoai/ 在…

Flux功能介紹,完整使用示例,與Mono對比

以下是關于Reactor框架中Flux與Mono的功能介紹、使用示例及對比分析&#xff1a; Flux功能介紹 核心定義 Flux是Reactor庫中的核心接口&#xff0c;表示一個異步的、包含零到多個元素的序列&#xff08;類似流式數據處理&#xff09;[3][4][7]。它可以處理無限長度的數據流&am…

Git使用基本指南

一、Git 基礎配置 首先需要配置用戶信息&#xff0c;讓 Git 知道你是誰&#xff1a; git config --global user.name "你的名字" git config --global user.email "你的郵箱example.com" 如果需要查看配置信息&#xff0c;可以使用&#xff1a; git co…

【入門】【例17.3】 內功逼毒

| 時間限制&#xff1a;C/C 1000MS&#xff0c;其他語言 2000MS 內存限制&#xff1a;C/C 64MB&#xff0c;其他語言 128MB 難度&#xff1a;中等 分數&#xff1a;100 OI排行榜得分&#xff1a;12(0.1分數2難度) 出題人&#xff1a;root | 描述 黃蓉中了毒&#xff0c;在 t 時…

蘋果芯片macOS安裝版Homebrew(親測)

在Linux服務器上安裝一個軟件常用yum&#xff0c;apt、dnf命令&#xff0c;同樣macOS可以使用brew命令來安裝軟件。 brew會自動幫你下載、解壓、安裝和配置&#xff0c;更重要的是&#xff1a;它還會自動處理好軟件之間的依賴關系&#xff0c;它將所有軟件都安裝在獨立的統一目…

uniapp+vue3做小程序,獲取容器高度

小程序獲能用createSelectorQuery&#xff0c;如果是子組件&#xff0c;后面可以額外加一個參數in來指定獲取dom的范圍。小程序里面可以直接.in(this)&#xff0c;但是vue3沒有this了&#xff0c;那就只能通過getCurrentInstance去獲取當前實例代替this &#xff0c;注意這里需…

【網工】華為配置專題進階篇①

目錄 ■浮動路由和BFD配置 ▲浮動路由 基本配置示例 ▲BFD ▲驗證命令 ▲測試連通性 ■路由綜合實驗RIP OSPF BGP ■浮動路由和BFD配置 ▲浮動路由 浮動路由&#xff1a;設置preference 浮動路由是一種備份路由機制&#xff0c;當主路由失效時&#xff0c;浮動路由會…

DeepLegal AI:智能法律文檔審查與合規助手+MVP

1. 商業價值與市場機會 DeepLegal AI旨在革新法律行業中耗時且資源密集型的文檔審查和合規流程。該應用將利用DeepSeek先進的語言模型能力&#xff0c;為律師事務所、企業法務部門和合規團隊提供一個高效、準確且經濟的解決方案。 市場機會&#xff1a; 法律科技市場正經歷爆…

使用 Rust 編寫簡單計算器

在編程語言的世界中&#xff0c;Rust 以其安全性和高性能而聞名。今天&#xff0c;我們將通過一個簡單的項目來探索 Rust 的魅力 —— 編寫一個簡單的命令行計算器。這個計算器將支持基本的算術運算&#xff08;加、減、乘、除&#xff09;&#xff0c;并且可以通過用戶輸入進行…

清華大學:《AI賦能教育 :高考志愿填報工具使用指南》下載

志愿填報的認知革命已經到來 “分數出來了&#xff0c;但不知道能上什么學校……” “喜歡這個專業&#xff0c;但不知道就業前景怎么樣&#xff1f;” “到底是選熱門專業還是選興趣愛好&#xff1f;” 這些讓百萬家庭徹夜難眠的問題&#xff0c;你是否正在經歷&#xff1f; …

【科技公司的管理】

如何打造高效、人性化的目標驅動型公司&#xff1f;——OKR管理法績效薪酬體系全指南 你希望公司目標清晰、員工高效、多勞多得&#xff0c;同時避免馬斯克式的“冷血管理”&#xff0c;兼顧員工生活需求。以下是系統性解決方案&#xff0c;涵蓋目標設定&#xff08;OKR&#x…

小白成長之路--nginx基礎配置(一)

文章目錄 一、概述1.1 Nginx 特點1.2 Nginx 作用1.3Nginx工作原理 二、Nginx服務搭建2.1安裝2.2 目錄結構2.3 配置文件作用2.4 nginx,conf配置文件詳解2.5 核心命令2.6 Nginx信號三.Nginx3.1啟動 總結 一、概述 Nginx 是開源、高性能、高可靠的 Web服務器 和反向代理服務器&am…

從最基礎的float布局開始學前端

前端學習其實不難&#xff0c;我們先從float布局講起&#xff0c;寫一個最簡單的導航欄&#xff1a;Logo在左&#xff0c;導航鏈接在右。下面是示例代碼&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"…

12. TypeScript 高級類型

TypeScript 中的高級類型包括映射類型、條件類型、字面量類型和遞歸類型等強大結構。這些特性使開發者能夠表達類型之間更復雜的關系&#xff0c;從而處理邊緣情況&#xff0c;并定義更動態、更靈活的類型系統。 一、映射類型 TypeScript 映射類型&#xff08;Mapped Types&a…

韓國證券交易所(KRX)全生態接入系統技術白皮書

核心價值&#xff1a;為全球最活躍的衍生品市場&#xff08;日均交易量480億美元&#xff09;提供 5μs延遲引擎全合規認證&#xff0c;助力中資機構搶占韓國78%衍生品交易份額 一、KRX市場機遇與準入壁壘 1.1 核心數據錨定&#xff08;2025Q2&#xff09; 指標數值全球競爭力…