亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go語(yǔ)言通道之無(wú)緩沖通道與緩沖通道詳解

 更新時(shí)間:2023年06月18日 17:11:43   作者:香吧香  
通道是一種特殊的數(shù)據(jù)結(jié)構(gòu),可以在協(xié)程之間進(jìn)行傳遞數(shù)據(jù),從而實(shí)現(xiàn)協(xié)程之間的通信和同步,本文就來(lái)和大家講講Go語(yǔ)言通道中的無(wú)緩沖通道與緩沖通道吧

1.通道定義  

在多個(gè)協(xié)程之間進(jìn)行通信和管理,可以使用 Go 語(yǔ)言提供的通道(Channel)類型。通道是一種特殊的數(shù)據(jù)結(jié)構(gòu),可以在協(xié)程之間進(jìn)行傳遞數(shù)據(jù),從而實(shí)現(xiàn)協(xié)程之間的通信和同步。多個(gè)協(xié)程可以同時(shí)讀寫(xiě)同一個(gè)通道,通過(guò)通道來(lái)進(jìn)行數(shù)據(jù)的傳遞和共享。

通道遵循先入先出(First In First Out)的原則,保證收發(fā)數(shù)據(jù)的順序。通道是一個(gè)特殊的數(shù)據(jù)類型,在使用之前必須定義和創(chuàng)建通道變量,定義通道的語(yǔ)法如下:

var name chan type

語(yǔ)法格式說(shuō)明如下:

1)var是Go語(yǔ)言關(guān)鍵字,用于定義變量。

2)name是通道變量名稱,可自行命名。

3)chan是Go語(yǔ)言關(guān)鍵字,將變量定義為通道類型。

4)type是通道存放的數(shù)據(jù)類型。

通道定義之后,還需要使用關(guān)鍵字make創(chuàng)建通道,通道的創(chuàng)建語(yǔ)法如下:

name := make(chan type, num)

語(yǔ)法格式說(shuō)明如下:

1)name是通道變量名稱,可自行命名。

2)make是Go語(yǔ)言關(guān)鍵字,用于創(chuàng)建通道。

3)chan type的chan是Go語(yǔ)言關(guān)鍵字,type是通道能存放的數(shù)據(jù)類型。

4)num是通道存放數(shù)據(jù)的數(shù)量上限。

在實(shí)際編程中,我們直接使用關(guān)鍵字make創(chuàng)建通道即可使用,這樣能省去定義通道的過(guò)程,示例代碼如下:

// 定義和創(chuàng)建通道
    var ch chan string
    ch = make(chan string)
    // 直接創(chuàng)建通道,無(wú)須定義
    ch := make(chan string)

通道創(chuàng)建之后,使用通道完成寫(xiě)入和讀取數(shù)據(jù)操作。在通道里面寫(xiě)入和讀取數(shù)據(jù)需要由<-操作符實(shí)現(xiàn),使用說(shuō)明如下:

// 構(gòu)建通道
    ch := make(chan string)
    // 往通道寫(xiě)入數(shù)據(jù)
    ch <- "Hello"
    // 從通道獲取數(shù)據(jù),賦予變量s
    s := <- ch

2.無(wú)緩沖通道

無(wú)緩沖通道是 Go 語(yǔ)言中一種常見(jiàn)的通道類型,也稱為同步通道或阻塞通道。無(wú)緩沖通道的特點(diǎn)是在發(fā)送和接收數(shù)據(jù)時(shí),必須有另外一個(gè)協(xié)程同時(shí)進(jìn)行相反的操作,否則會(huì)阻塞當(dāng)前協(xié)程。 具體來(lái)說(shuō),無(wú)緩沖通道的特點(diǎn)如下:

  • 發(fā)送和接收操作是同步的,即發(fā)送操作必須等待接收操作完成后才能繼續(xù)執(zhí)行,接收操作也必須等待發(fā)送操作完成后才能繼續(xù)執(zhí)行。
  • 無(wú)緩沖通道的容量為 0,即只有在發(fā)送和接收操作同時(shí)進(jìn)行時(shí)才能傳遞數(shù)據(jù),否則會(huì)阻塞當(dāng)前協(xié)程。
  • 無(wú)緩沖通道的數(shù)據(jù)傳遞是按照先進(jìn)先出的順序進(jìn)行的,即發(fā)送的數(shù)據(jù)會(huì)按照發(fā)送的順序被接收。 無(wú)緩沖通道可以用于協(xié)程之間的同步和通信,例如在生產(chǎn)者和消費(fèi)者模式中,可以使用無(wú)緩沖通道來(lái)傳遞數(shù)據(jù),從而保證生產(chǎn)者和消費(fèi)者之間的同步和互斥。同時(shí),無(wú)緩沖通道的使用也可以避免數(shù)據(jù)競(jìng)爭(zhēng)問(wèn)題,從而提高程序的安全性和可靠性。

通道是通過(guò)關(guān)鍵字make創(chuàng)建的,在創(chuàng)建過(guò)程中,如果沒(méi)有設(shè)置參數(shù)num,則視為創(chuàng)建無(wú)緩沖通道。無(wú)緩沖通道(Unbuffered Channel)是指在獲取數(shù)據(jù)之前沒(méi)有能力保存數(shù)據(jù)的通道,這種類型的通道要求兩個(gè)Goroutine同時(shí)處于執(zhí)行狀態(tài)才能完成寫(xiě)入和獲取操作。

如果兩個(gè)Goroutine沒(méi)有同時(shí)準(zhǔn)備,某一個(gè)Goroutine執(zhí)行寫(xiě)入或獲取操作將會(huì)處于阻塞等待狀態(tài),另一個(gè)Goroutine無(wú)法執(zhí)行寫(xiě)入或獲取操作,程序?qū)?huì)提示異常,這種類型的通道執(zhí)行寫(xiě)入和獲取的交互行為是同步,任意一個(gè)操作都無(wú)法離開(kāi)另一個(gè)操作單獨(dú)存在。

當(dāng)我們使用無(wú)緩沖通道的時(shí)候,必須注意通道變量的操作,確保程序中有兩個(gè)或兩個(gè)以上的Goroutine同時(shí)執(zhí)行通道的讀寫(xiě)操作,讀寫(xiě)操作必須是一讀一寫(xiě),不能只讀不寫(xiě)或只寫(xiě)不讀,示例如下:

// 只寫(xiě)入數(shù)據(jù),不讀取
    ch := make(chan string)
    ch <- "Tom"
    fmt.Println("wait goroutine")
    // 只讀取數(shù)據(jù),不寫(xiě)入
    ch := make(chan string)
    <- ch
    fmt.Println("wait goroutine")

通道數(shù)據(jù)只寫(xiě)入不讀取或者只讀取不寫(xiě)入都會(huì)提示fatal error: all goroutines are asleep–deadlock異常,如果需要實(shí)現(xiàn)通道數(shù)據(jù)獲取超時(shí)檢測(cè),可以使用關(guān)鍵字select實(shí)現(xiàn)。

如果程序中僅有一個(gè)Goroutine,使用通道讀寫(xiě)數(shù)據(jù)也會(huì)導(dǎo)致異常,比如在主函數(shù)main()中對(duì)通道寫(xiě)入數(shù)據(jù),再讀取通道數(shù)據(jù),示例如下:

package main
    import (
        "fmt"
    )
    func main() {
        // 構(gòu)建通道
        ch := make(chan string)
        // 寫(xiě)入通道數(shù)據(jù)
        ch <- "Tom"
        // 讀取通道數(shù)據(jù)
        <-ch
        fmt.Println("wait goroutine")
    }

如果在發(fā)送和接收數(shù)據(jù)時(shí)出現(xiàn)異常,則會(huì)引發(fā)程序異常。例如,如果我們?cè)诎l(fā)送數(shù)據(jù)之前關(guān)閉通道,則會(huì)引發(fā)一個(gè)運(yùn)行時(shí)異常。為了避免這種情況的發(fā)生,我們可以使用 defer 語(yǔ)句在函數(shù)退出之前關(guān)閉通道。例如:

func main() {
    ch := make(chan int)
    defer close(ch) // 使用 defer 關(guān)閉通道
    go func() {
        fmt.Println("開(kāi)始發(fā)送消息...")
        ch <- 1
        fmt.Println("消息發(fā)送完成。")
    }()
    fmt.Println("開(kāi)始接收消息...")
    msg := <-ch
    fmt.Printf("接收到的消息是:%d\n", msg)
    fmt.Println("消息接收完成。")
}

3.帶緩沖通道

帶緩沖通道(Buffered Channel)是在被獲取前能存儲(chǔ)一個(gè)或者多個(gè)數(shù)據(jù)的通道,這種類型的通道并不強(qiáng)制要求Goroutine之間必須同時(shí)完成寫(xiě)入和獲取。當(dāng)通道中沒(méi)有數(shù)據(jù)的時(shí)候,獲取動(dòng)作才會(huì)阻塞;當(dāng)通道沒(méi)有可用緩沖區(qū)存儲(chǔ)數(shù)據(jù)的時(shí)候,寫(xiě)入動(dòng)作才會(huì)阻塞。

在無(wú)緩沖通道的基礎(chǔ)上,只要為通道增加一個(gè)有限大小的存儲(chǔ)空間就能形成帶緩沖通道。帶緩沖通道在寫(xiě)入時(shí)無(wú)須等待獲取即可再次執(zhí)行下一輪寫(xiě)入,并且不會(huì)發(fā)生阻塞,只有當(dāng)存儲(chǔ)空間滿了才會(huì)發(fā)生阻塞。同理,如果帶緩沖通道中有數(shù)據(jù),獲取時(shí)將不會(huì)發(fā)生阻塞,直到通道中沒(méi)有數(shù)據(jù)可讀時(shí),通道才會(huì)阻塞。

從通道的定義角度分析,帶緩沖和無(wú)緩沖通道的區(qū)別在于參數(shù)num。創(chuàng)建通道的時(shí)候,如果沒(méi)有設(shè)置參數(shù)num,則默認(rèn)參數(shù)值為0,通道為無(wú)緩沖通道,所以寫(xiě)入和獲取數(shù)據(jù)必須同時(shí)進(jìn)行才不會(huì)因阻塞而異常;如果參數(shù)num大于0,則寫(xiě)入和獲取數(shù)據(jù)無(wú)須同步執(zhí)行,因?yàn)橥ǖ烙凶銐虻目臻g存放數(shù)據(jù)。

由于帶緩沖通道沒(méi)有讀寫(xiě)同步限制,我們可以在同一個(gè)Goroutine中執(zhí)行多次寫(xiě)入和獲取操作,具體示例如下:

package main
    import "fmt"
    func main() {
        // 創(chuàng)建一個(gè)3個(gè)元素緩沖大小的整型通道
        ch := make(chan int, 3)
        // 查看當(dāng)前通道的大小
        fmt.Println(len(ch))
        // 發(fā)送3個(gè)整型元素到通道
        for i := 0; i < 3; i++ {
             ch <- i
        }
        // 查看當(dāng)前通道的大小
        fmt.Println(len(ch))
        for i := 0; i < 3; i++ {
             fmt.Println(<-ch)
        }
        // 查看當(dāng)前通道的大小
        fmt.Println(len(ch))
        // 查看當(dāng)前通道的容量
        fmt.Println(cap(ch))
    }

上述代碼的說(shuō)明如下:

1)通過(guò)for執(zhí)行了3次循環(huán),每次循環(huán)將變量i寫(xiě)入通道,然后通過(guò)3次循環(huán)從通道獲取數(shù)據(jù)并輸出。

2)通道寫(xiě)入和讀取數(shù)據(jù)的時(shí)候,使用len()函數(shù)獲取通道已有的數(shù)據(jù)量,判斷當(dāng)前通道存儲(chǔ)的數(shù)據(jù)量是否達(dá)到上限,這樣可以防止程序在運(yùn)行時(shí)提示異常。

3)使用cap()函數(shù)能獲取通道的容量大小,即獲取創(chuàng)建通道m(xù)ake()的參數(shù)num的大小。帶緩沖通道在很多特性上和無(wú)緩沖通道類似,無(wú)緩沖通道可以看作長(zhǎng)度為0的帶緩沖通道。

根據(jù)這個(gè)特性,帶緩沖通道在下列情況下會(huì)發(fā)生阻塞:

1)帶緩沖通道的存儲(chǔ)數(shù)據(jù)達(dá)到上限時(shí),再次寫(xiě)入數(shù)據(jù)將發(fā)生阻塞而導(dǎo)致異常。

2)帶緩沖通道沒(méi)有存儲(chǔ)數(shù)據(jù)時(shí),獲取數(shù)據(jù)將發(fā)生阻塞而導(dǎo)致異常。

Go語(yǔ)言為什么對(duì)通道要限制長(zhǎng)度?因?yàn)槎鄠€(gè)Goroutine之間使用通道必然存在寫(xiě)入和獲取操作,這種模式類型的典型例子為生產(chǎn)者消費(fèi)者模式。如果不限制通道長(zhǎng)度,當(dāng)寫(xiě)入數(shù)據(jù)速度大于獲取速度,內(nèi)存將不斷膨脹直到應(yīng)用崩潰。因此,限制通道的長(zhǎng)度有利于約束數(shù)據(jù)生產(chǎn)速度,生產(chǎn)數(shù)據(jù)量必須在數(shù)據(jù)消費(fèi)速度+通道長(zhǎng)度的范圍內(nèi),這樣才能正常地處理數(shù)據(jù)。

到此這篇關(guān)于Go語(yǔ)言通道之無(wú)緩沖通道與緩沖通道詳解的文章就介紹到這了,更多相關(guān)Go通道內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Go語(yǔ)言實(shí)現(xiàn)線性查找算法和二分查找算法

    詳解Go語(yǔ)言實(shí)現(xiàn)線性查找算法和二分查找算法

    線性查找又稱順序查找,它是查找算法中最簡(jiǎn)單的一種。二分查找,也稱折半查找,相比于線性查找,它是一種效率較高的算法。本文將用Go語(yǔ)言實(shí)現(xiàn)這兩個(gè)查找算法,需要的可以了解一下
    2022-12-12
  • golang時(shí)間字符串和時(shí)間戳轉(zhuǎn)換的案例

    golang時(shí)間字符串和時(shí)間戳轉(zhuǎn)換的案例

    這篇文章主要介紹了golang時(shí)間字符串和時(shí)間戳轉(zhuǎn)換的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Golang?Makefile示例深入講解使用

    Golang?Makefile示例深入講解使用

    一次偶然的機(jī)會(huì),在?github?上看到有人用?Makefile,就嘗試了一下,發(fā)現(xiàn)真的非常合適,Makefile?本身就是用來(lái)描述依賴的,可讀性非常好,而且與強(qiáng)大的?shell?結(jié)合在一起,基本可以實(shí)現(xiàn)任何想要的功能
    2023-01-01
  • 線上問(wèn)題排查之golang使用json進(jìn)行對(duì)象copy

    線上問(wèn)題排查之golang使用json進(jìn)行對(duì)象copy

    這篇文章主要介紹了線上問(wèn)題排查之golang使用json進(jìn)行對(duì)象copy,文章圍繞golang使用json進(jìn)行對(duì)象copy的內(nèi)存溢出問(wèn)題排查展開(kāi)詳細(xì)內(nèi)容需要的小伙伴可以參考一下
    2022-06-06
  • Go每日一庫(kù)之zap日志庫(kù)的安裝使用指南

    Go每日一庫(kù)之zap日志庫(kù)的安裝使用指南

    這篇文章主要為大家介紹了Go每日一庫(kù)之zap安裝使用示例學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • GoLang 逃逸分析的機(jī)制詳解

    GoLang 逃逸分析的機(jī)制詳解

    這篇文章主要介紹了GoLang-逃逸分析的機(jī)制詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • GO語(yǔ)言中的Map使用方法詳解

    GO語(yǔ)言中的Map使用方法詳解

    這篇文章主要給大家介紹了關(guān)于GO語(yǔ)言中Map使用方法的相關(guān)資料,在go語(yǔ)言中map是散列表的引用,map的類型是map[k]v,也就是常說(shuō)的k-v鍵值對(duì),需要的朋友可以參考下
    2023-08-08
  • go 熔斷原理分析與源碼解讀

    go 熔斷原理分析與源碼解讀

    這篇文章主要為大家介紹了go 熔斷原理分析與源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 詳解Go語(yǔ)言如何使用標(biāo)準(zhǔn)庫(kù)sort對(duì)切片進(jìn)行排序

    詳解Go語(yǔ)言如何使用標(biāo)準(zhǔn)庫(kù)sort對(duì)切片進(jìn)行排序

    Sort?標(biāo)準(zhǔn)庫(kù)提供了對(duì)基本數(shù)據(jù)類型的切片和自定義類型的切片進(jìn)行排序的函數(shù)。今天主要分享的內(nèi)容是使用?Go?標(biāo)準(zhǔn)庫(kù)?sort?對(duì)切片進(jìn)行排序,感興趣的可以了解一下
    2022-12-12
  • golang中為什么Response.Body需要被關(guān)閉詳解

    golang中為什么Response.Body需要被關(guān)閉詳解

    這篇文章主要給大家介紹了關(guān)于golang中為什么Response.Body需要被關(guān)閉的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08

最新評(píng)論