channelinactive觸發后不關閉channel_go那些事兒|channel使用及其實現原理

目錄?

  • channel背景

  • channel基本用法

  • channel應用場景

  • channel實現原理

    • channel數據結構

    • channel實現方式

  • channel注意事項

  • 閑聊

  • 歡迎加入我的公眾號【邁莫coding】 一起pk大廠

1channel背景

channel是Go的核心類型,是Go語言內置的類型,你無需引包,就能使用它。你可以把它看作一個管道,在Go語言中流傳著一句話,"執行業務處理的goroutine不要通過共享內存通信,要通過channel管道進行共享數據"

channel和Go的另一種特性goroutine一起為并發編程提供了優雅的,便利的方案,來應對并發場景。

2channel基本用法

channel的基本用法非常簡單,它提供了三種類型,分別為只能接收只能發送既能接收也能發送這三種類型。因此它的語法為:

chanstruct{} chan chan string // 既能接收也能發送

我們把既能發送也能接收的chan被稱為雙向chan,把只能接收或者只能發送的chan稱為單向chan。其中,"這個箭頭總是射向左邊的,元素類型總在最右邊。如果箭頭指向 chan,就表示可以往 chan 中塞數據;如果箭頭遠離 chan,就表示 chan 會往外吐數據。

通過make關鍵字,我們可以初始化一個chan,未初始化的chan的零值為nil。你可以設置他的容量,第二個參數為緩沖池的容量大小,也可以理解為即使chan未消費完,也可以存儲數據。

make(chan int, 8)
?

如果chan中還有數據,那么從這個chan中接收數據就不會阻塞,如果chan中數據未達到隊列容量,那么向該chan中存儲數據也不會阻塞,反之會阻塞。

還有一個知識點要記住:nil 是 chan 的零值,是一種特殊的 chan,對值是 nil 的 chan 的發送接收調用者總是會阻塞。

接下來,我們用代碼來學習一下chan的三種類型

  • 只能接收數據的chan

代碼示例

package main import "fmt"// a 表示只能接收數據的chanfunc goChanA(a chan int) {  b :=   fmt.Println("只能接收數據的channal[a]接收到的數據值為", b)}func main() {  ch := make(chan int, 2)  go goChanA(ch)  // 往ch中寫入數據值  ch 2  time.Sleep(time.Second)}

結果

只能接收數據的channal[a]接收到的數據值為 2
?
  • 只能發送數據的chan

代碼示例

package main import "fmtfunc main() {  ch := make(chan  ch }

往 chan 中發送一個數據使用“ch

這里的 ch 是 chan int 類型或者是 chan

3channel應用場景

  • 數據交流:當作并發的 buffer 或者 queue,解決生產者 - 消費者問題。多個 goroutine 可以并發當作生產者(Producer)和消費者(Consumer)。

  • 數據傳遞:一個goroutine將數據交給另一個goroutine,相當于把數據的擁有權托付出去。

  • 信號通知:一個goroutine可以將信號(closing,closed,data ready等)傳遞給另一個或者另一組goroutine。

  • 任務編排:可以讓一組goroutine按照一定的順序并發或者串行的執行,這就是編排功能。

  • 鎖機制:利用channel實現互斥機制。

4channel實現原理

channel數據結構

channel一個類型管道,通過它可以在goroutine之間發送消息和接收消息。它是golang在語言層面提供的goroutine間的通信方式。

眾所周知,Go依賴于稱為CSP(Communicating Sequential Processes)的并發模型,通過 Channel實現這種同步模式。?

channel結構體

//path:src/runtime/chan.gotype hchan struct {  qcount uint          // 當前隊列列中剩余元素個數  dataqsiz uint        // 環形隊列長度,即可以存放的元素個數  buf unsafe.Pointer   // 環形隊列列指針  elemsize uint16      // 每個元素的??  closed uint32        // 標識關閉狀態  elemtype *_type      // 元素類型  sendx uint           // 隊列下標,指示元素寫?入時存放到隊列列中的位置 x  recvx uint           // 隊列下標,指示元素從隊列列的該位置讀出    recvq waitq          // 等待讀消息的goroutine隊列  sendq  waitq         // 等待寫消息的goroutine隊列  lock mutex           // 互斥鎖,chan不允許并發讀寫}

從數據結構可以看出channel由隊列、類型信息、goroutine等待隊列組成。? ? ? ?

channel實現方式

chan內部實現了一個緩沖隊列作為緩沖區,隊列的長度是創建chan時指定的。

下圖展示了可緩存6個元素的channel示意圖:

64d45f6d3923fdda3d340b4497b4e36a.png

  • dataqsiz:指向隊列的長度為6,即可緩存6個元素

  • buf:指向隊列的內存,隊列中還剩余兩個元素

  • qcount:當前隊列中剩余的元素個數

  • sendx:指后續寫入元素的位置

  • recvx:指從該位置讀取數據

等待隊列

從channel中讀數據,如果channel緩沖區為空或者沒有緩沖區,當前goroutine會被阻塞;向channel中寫數據,如果channel緩沖區已滿或者沒有緩沖區,當前goroutine會被阻塞。

被阻塞的goroutine將會被掛在channel的等待隊列中:

  • 因讀阻塞的goroutine會被向channel寫入數據的goroutine喚醒

  • 因寫阻塞的goroutine會被從channel讀數據的goroutine喚醒

下面展示了一個沒有緩沖區的channel,有幾個goroutine阻塞等待數據:

0fdb36a14ce7d88223749c7d3bf990d3.png

注意,一般情況下recvq和sendq至少有一個為空。只有一個例外,那就是同一個goroutine使用select語句向channel一邊寫數據一邊讀數據。

向channel寫數據

  • 流程圖:

86e83d00c8ac28899200226f51871608.png

  • 詳細過程

    • 如果recvq隊列不為空,說明緩沖區沒有數據或者沒有緩沖區,此時直接從recvq等待隊列中取出一個G,并把數據寫入,最后把該G喚醒,結束發送過程;

    • 如果緩沖區有空余位置,則把數據寫入緩沖區中,結束發送過程;

    • 如果緩沖區沒有空余位置,則把數據寫入G,將當前G寫入sendq隊列,進入休眠,等待被讀goroutine喚醒;

從channel讀數據

  • 流程圖

d163599fbb3bd7e9daf87a61562069f0.png

  • 詳細過程

    • 如果等待發送隊列sendq不為空,且沒有緩沖區,直接從sendq隊列中取出G,把G中數據讀出,最后把G喚醒,結束讀取過程;

    • 如果等待發送隊列sendq不為空,說明緩沖區已滿,從緩沖隊列中首部讀取數據,從sendq等待發送隊列中取出G,把G中的數據寫入緩沖區尾部,結束讀取過程;

    • 如果緩沖區中有數據,則從緩沖區取出數據,結束讀取過程;

5channel注意事項
  • 向已經關閉的channel中寫入數據會發生Panic

  • 關閉已經關閉的channel會發生Panic

  • 關閉值為nil的channel會發生Panic

6閑聊

  • 讀完文章,自己是不是和channel管道的cp率又提高了

  • 我是邁莫,歡迎大家和我交流

原創不易,覺得文章寫得不錯的小伙伴,點個贊? 鼓勵一下吧~

7歡迎加入我的公眾號【邁莫coding】 一起pk大廠

  • 邁莫coding歡迎客官的到來

c71cb360c98bf6eb4b13a2f1c7b9935b.png

68ccefea8c1c3fb7b132f83ccc9b8973.png

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

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

相關文章

遞推-練習2--noi3525:上臺階

遞推-練習2--noi3525:上臺階 一、心得 二、題目 3525:上臺階 總時間限制: 1000ms內存限制: 65536kB描述樓梯有n(100 > n > 0)階臺階,上樓時可以一步上1階,也可以一步上2階,也可以一步上3階,編程計算共有多少種不同的走法。 輸入輸入的每一行包括一組測試數據&…

matlab畫信號頻譜

為了讓大學生活充實一點,多學點東西,我選修了《數字信號處理》。現在充實得不要不要的。 clc close all clear%參數設置% Fs 1000; % Sampling frequency T 1/Fs; % Sampling period L 1500; …

關于字節序(大端法、小端法)的定義

關于字節序(大端法、小端法)的定義《UNXI網絡編程》定義:術語“小端”和“大端”表示多字節值的哪一端(小端或大端)存儲在該值的起始地址。小端存在起始地址,即是小端字節序;大端存在起始地址,即是大端字節序。 也可以說&#xff…

html div初始隱藏點擊可見_3種CSS3移動手機隱藏菜單UI界面代碼解析/附源碼下載...

這是一款效果非常酷的jQuery和CSS3移動手機隱藏菜單UI界面設計。這個UI設計共有三種不同的打開隱藏菜單的效果,分別為滑動顯示,Material Design風格效果和展開式效果。使用方法HTML結構這三種不同的隱藏菜單的HTML結構大致基本相同。第一種滑動效果菜單的…

《數據結構與抽象:Java語言描述(原書第4版)》一P.4.1 標識類

本節書摘來華章計算機《數據結構與抽象:Java語言描述(原書第4版)》一書中的第1章 ,[美]弗蘭克M.卡拉諾(Frank M. Carrano) 蒂莫西M.亨利(Timothy M. Henry) …

【SVM】簡單介紹(一)

1、結構風險最小化 我們想要在未知的數據上得到低的錯誤率&#xff0c;這叫做structural risk minimization;相對的&#xff0c;訓練誤差叫做empirical risk minimization 要是我們能有這樣一個式子就好了&#xff1a; Test error rate <train error rate f(N,h,p)\text {…

L8_2

4.留下pid為12345的那個sh進程&#xff0c;殺死系統中所有其它sh進程 ps –ef|grep sh |awk ‘{if($2!”12345”) {print “kill “$2}}’ >killpid.sh cat killpid.sh ./killpid.sh 5. 根據以下日志文件&#xff0c;計算使用各種瀏覽器的人所占的百分比&#xff08;注意先排…

iOS 打包iPa

http://blog.fir.im/how-to-build-adhoc-ipa/ 之前都是打包好ipa然后發送給客戶&#xff0c;特麻煩&#xff0c;fir.im網站不錯 迅速獲取自己手機的udid: http://fir.im/udid 網頁安裝ipa&#xff1a; http://fir.im/cxsv 轉載于:https://www.cnblogs.com/shidaying/p/4829102…

# 遍歷刪除字典元素_第六章 字典

一、使用字典一個簡單的字典字典是一系列鍵——值對。每個鍵都與一個值相關聯&#xff0c;可以使用鍵來訪問與之相關聯的值。與鍵相關聯的值可以是數字、字符串、列表乃至字典。事實上&#xff0c;可將任何Python對象用作字典中的值。在Python中&#xff0c;字典用放在花括號{}…

user-select屬性用法

這是在css3 UI規范中新增的一個功能&#xff0c;用來控制內容的可選擇性。 auto——默認值&#xff0c;用戶可以選中元素中的內容none——用戶不能選擇元素中的任何內容text——用戶可以選擇元素中的文本element——文本可選&#xff0c;但僅限元素的邊界內(只有IE和FF支持)all…

弄清 CSS3 的 transition 和 animation

弄清 CSS3 的 transition 和 animation 原文:弄清 CSS3 的 transition 和 animation弄清 CSS3 的 transition 和 animation transition transition 屬性是transition-property,transition-duration,transition-timing-function,transition-delay的簡稱,用于設定一個元素的兩個狀…

【SVM】簡單介紹(二)

1、SVM另一種推法 我們不管分類平面&#xff0c;直接去假設Margin的兩個邊界&#xff1a; Plus-plane {x:w?xb1}Minus-plane {x:w?xb?1}\begin{aligned} & \text { Plus-plane }\{\boldsymbol{x}: \boldsymbol{w} \cdot \boldsymbol{x}b1\} \\ & \text { Minus-plan…

圖像像素點賦值_Python 圖像處理 OpenCV (2):像素處理與 Numpy 操作以及 Matplotlib 顯示圖像...

普通操作1. 讀取像素讀取像素可以通過行坐標和列坐標來進行訪問&#xff0c;灰度圖像直接返回灰度值&#xff0c;彩色圖像則返回B、G、R三個分量。需要注意的是&#xff0c; OpenCV 讀取圖像是 BGR 存儲顯示。灰度圖片讀取操作&#xff1a;import cv2 as cv# 灰度圖像讀取gray_…

cocopods

一、什么是CocoaPods 1、為什么需要CocoaPods 在進行iOS開發的時候&#xff0c;總免不了使用第三方的開源庫&#xff0c;比如SBJson、AFNetworking、Reachability等等。使用這些庫的時候通常需要&#xff1a; 下載開源庫的源代碼并引入工程向工程中添加開源庫使用到的framework…

CSS3學習手記(10) 過渡

CSS3過渡 允許css的屬性值在一定的時間內平滑地過渡在鼠標單擊、獲取焦點、被點擊或對元素任何改變中觸發&#xff0c;并圓滑地以動畫效果改變CSS的屬性值transition transition-property屬性檢索或設置對象中的參與過渡的屬性 語法 transition-property:none|all|property …

POJ 1286 Necklaces of Beads (Burnside定理,有限制型)

題目鏈接&#xff1a;http://vjudge.net/problem/viewProblem.action?id11117 就是利用每種等價情形算出置換節之后算組合數 #include <stdio.h> #include <cstring> #include <cstdlib> #include <algorithm> #include <cmath>using namespace…

全局搜索快捷鍵_Windows 自帶的聚合搜索來了,與 Mac 的 Spotlight 相比體驗如何?...

最近 Windows 10 推出了自帶的聚合搜索功能 PowerToys Run&#xff0c;取代了之前的 WinR。蘋果的 macOS 以人性化著稱&#xff0c;有幾個功能讓 Windows 用戶一直很羨慕&#xff0c;比如全局的聚合搜索工具 Spotlight。在任何界面 command空格&#xff0c;輸入關鍵字就能搜索電…

transform你不知道的那些事

transform是諸多css3新特性中最打動我的&#xff0c;因為它讓方方正正的box module變得真實了。 transform通過一組函數實現了對盒子大小、位置、角度的2D或者3D變換。不過很長時間內&#xff0c;我對以下問題都想不太明白&#xff1a; 1、尺寸縮放scale與zoom變換有何不同&…

【SVM】簡單介紹(三)

我們考慮SVM的對偶問題&#xff0c;我們通常是在對偶空間中進行求解的。 1、Lagrange Multipliers 對于一個很一般的問題 Minimize f(x)subject to {a(x)≥0b(x)≤0c(x)0\begin{aligned} \text { Minimize } & f(x) \\ \text { subject to } \quad & \left\{\begin{a…

玩轉iOS開發:NSURLSession講解(三)

文章分享至我的個人技術博客: https://cainluo.github.io/14986211698053.html 前言 雖然前面兩講都是說了NSURLSession的一些理論上的知識, 但我們現在起碼對NSURLSession有個大概的了解, 并不會像一開始的那樣, 一臉懵逼的看著, 這個請求是什么鬼, 那個方法是什么鬼, Task是什…