golang channel

来源:https://www.cnblogs.com/elve960520/archive/2023/11/16/17837202.html
-Advertisement-
Play Games

”不要以共用記憶體的方式來通信,相反,要通過通信來共用記憶體“ golang 的一個思想,不整文的,整點武的,具體來看channel 怎麼做的 有一個很關鍵的 golang MPG 模型再單獨分析,這篇先只分析 channel 定義 // runtim/chan.go type hchan struct ...


”不要以共用記憶體的方式來通信,相反,要通過通信來共用記憶體“
golang 的一個思想,不整文的,整點武的,具體來看channel 怎麼做的
有一個很關鍵的 golang MPG 模型再單獨分析,這篇先只分析 channel

定義

// runtim/chan.go

type hchan struct {
	qcount   uint           // 通道里的元素數量
	dataqsiz uint           // 通道的總大小
	buf      unsafe.Pointer // 通道底層迴圈數組的指針
	elemsize uint16 // 每個元素的大小
	closed   uint32 // 通道是否關閉,不能重覆關閉,會 panic
	elemtype *_type // 通道里元素的類型
	sendx    uint   // 通道里發送元素的下標
	recvx    uint   // 接受元素的下標
	recvq    waitq  // 準備接受的協程鏈表
	sendq    waitq  // 準備發送的寫成鏈表

	lock mutex // 通道鎖,chan 是併發安全的
}

鏈表,保存發送或接受協程

// runtim/chan.go

type waitq struct {
	first *sudog
	last  *sudog
}

初始化

channel使用 make 初始化

c  := make(chan int) // 無緩衝
c2 := make(chan int,10) // 有緩衝

當無緩衝時,直接創建,當有緩衝時,還要調用 mallocgc 函數,申請空間,具體代碼可以看 runtime/chan.go

發送數據

使用來說很簡單,下麵的代碼如果 channel 滿了或者無緩衝無接受者的話就會阻塞

c <- 10

具體發送代碼在 runtime/chan.go(chansend) 函數,就不貼代碼了,直接分析流程

除了必要的一些檢查之外,先對 channel 進行加鎖,如果 channel 已經關閉了,就解鎖退出
然後判斷接收區有沒有 goroutine 在等待,如果有的話,直接把數據拷貝給接收區的 goroutine,然後喚醒 goroutine
否則看緩衝區是否滿了,如果沒滿,就把數據拷貝到緩衝區sendx處,然後 sendx++,qcount++,退出
如果緩衝區也滿了,則把發送的 goroutine 放入到發送 sendq 隊列
一個流程就結束了

接受數據

x := <- c

具體關閉代碼在 runtime/chan.go(chanrecv)

先進行檢查,判斷 channel 是否是空的,如果是空的直接返回(判空條件是qcount == 0 並且sendq里沒有 goroutine)
然後加鎖
然後判斷 channel 是否已經關閉,關閉的話直接返回變數類型的空值
如果緩衝區有數據,則直接拷貝緩衝區數據到接受,recvx++,qcount--
如果上述都不符合,則把接受goroutine 保存到接受隊列

關閉通道

close(c)

源碼在 runtime/chan.go(closechan)

先加鎖,如果已經關閉了,則 panic
然後將 close 置為 1
把所有的接受隊列填充空值並喚醒
把所有的發送隊列喚醒,讓他們 panic

各種情況處理

close 一個正常的 channel 會正常,否則都會 panic,也就是 close 只能正確的調用一次
發送一個 close 的 channel 會 panic,發送一個 nil 的 channel 會一直阻塞
接受一個 close 的 channel 會接受到 0 值,接受一個 nil 的 channel 會一直阻塞

參考

Go 程式員面試筆試寶典-通道
圖解Golang channel源碼
Go面試題(五):圖解 Golang Channel 的底層原理


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 需求:客戶的電腦都只能訪問內,伺服器可以訪問外網,客戶電腦使用的項目中用到了高德webapi2.0。10.200.31.45:32100是我們的web伺服器。 網上基本上都是對高德webapi1.4的配置方式,而web2.0有一些差別。 1.前端修改高德地圖的js應用 如果是index.html引入 ...
  • 最近做的幾個項目經常遇到這樣的需求,要在表格上增加一個自定義表格欄位設置的功能。就是用戶可以自己控制那些列需要展示。在幾個項目里都實現了一遍,每個項目的需求又都有點兒不一樣,迭代了很多版,所以抽時間把這個功能封裝了個組件:@silverage/table-custom,將這些差別都集成了進去,方便今... ...
  • 大綱 本文內容更多的是講講使用 vuex 的一些心得想法,所以大概會講述下麵這些點: Q1:我為什麼會想使用 vuex 來管理數據狀態交互? Q2:使用 vuex 框架有哪些缺點或者說副作用? Q3:我是如何在項目里使用 vuex 的? 初識 vuex 對於 vuex,有人喜歡,有人反感 喜歡的人覺 ...
  • 微服務是一種軟體架構策略,將應用程式分解為一組解耦的、自治的服務。採用微服務架構將改善整體性能和可擴展性,本文將概述微服務設計和實施的基本考慮因素。 ...
  • 重構有利於項目的健壯和精簡,平時要養成重構的好習慣,“小步快走”,儘量避免留著統一重構的思想,積累很多技術債後重構精力、時間成本很大,風險也會大很多 ...
  • 需求落地分散式應用服務 將需求轉化為分散式應用服務的過程可以按照以下步驟進行: 理解需求:首先,你需要仔細閱讀和理解業務需求。與相關的利益相關者(如業務分析師、產品經理等)進行溝通,確保你對需求的理解是準確的。 設計架構:根據需求,設計一個適合的分散式應用架構。這包括確定應用的組件和模塊,以及它們之 ...
  • 十、數組 1、數組的概念 1)引出數組 需求:學校為了統計學生的信息,需要設計一個程式,要求如下,一共有十個學員,要求依次輸入各位學員的學號,並將其列印出來。 #include <iostream> int main() { int studentId1, studentId2, studentId ...
  • 寫在前面 技術這東西就得用,不用就會忘,之前寫博客感覺就是給自己記筆記用,還有大部分,估計睡在語雀里都落灰了,哈哈! 在Python領域,我覺得我還是算個小白吧,會寫講不明白,所以我決定想做一件事,先搞下flask這部分教程,看看能給大家說明白嗎,真的感覺和Java有很大區別,廢話不多說了,開整! ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...