go語言通道插入0 Go語言帶緩衝的通道

2021-10-13 08:10:52 字數 1498 閱讀 2060

go語言中有緩衝的通道(bufferedchannel)是一種在被接收前能儲存乙個或者多個值的通道。這種型別的通道並不強制要求goroutine之間必須同時完成傳送和接收。通道會阻塞傳送和接收動作的條件也會不同。只有在通道中沒有要接收的值時,接收動作才會阻塞。只有在通道沒有可用緩衝區容納被傳送的值時,傳送動作才會阻塞。

這導致有緩衝的通道和無緩衝的通道之間的乙個很大的不同:無緩衝的通道保證進行傳送和接收的goroutine會在同一時間進行資料交換;有緩衝的通道沒有這種保證。

在無緩衝通道的基礎上,為通道增加乙個有限大小的儲存空間形成帶緩衝通道。帶緩衝通道在傳送時無需等待接收方接收即可完成傳送過程,並且不會發生阻塞,只有當儲存空間滿時才會發生阻塞。同理,如果緩衝通道中有資料,接收時將不會發生阻塞,直到通道中沒有資料可讀時,通道將會再度阻塞。

無緩衝通道保證收發過程同步。無緩衝收發過程類似於快遞員給你**讓你下樓取快遞,整個遞交快遞的過程是同步發生的,你和快遞員不見不散。但這樣做快遞員就必須等待所有人下樓完成操作後才能完成所有投遞工作。如果快遞員將快遞放入快遞櫃中,並通知使用者來取,快遞員和使用者就成了非同步收發過程,效率可以有明顯的提公升。帶緩衝的通道就是這樣的乙個「快遞櫃」。

建立帶緩衝通道

如何建立帶緩衝的通道呢?參見如下**:通道例項:=make(chan通道型別,緩衝大小)

通道型別:和無緩衝通道用法一致,影響通道傳送和接收的資料型別。

緩衝大小:決定通道最多可以儲存的元素數量。

通道例項:被建立出的通道例項。

下面通過乙個例子中來理解帶緩衝通道的用法,參見下面的**:

packagemainimport"fmt"funcmain(){//建立乙個3個元素緩衝大小的整型通道ch:=make(chanint,3)//檢視當前通道的大小fmt.println(len(ch))//傳送3個整型元素到通道ch

**輸出如下:

**說明如下:

第8行,建立乙個帶有3個元素緩衝大小的整型型別的通道。

第11行,檢視當前通道的大小。帶緩衝的通道在建立完成時,內部的元素是空的,因此使用len()獲取到的返回值為0。

第14~16行,傳送3個整型元素到通道。因為使用了緩衝通道。即便沒有goroutine接收,傳送者也不會發生阻塞。

第19行,由於填充了3個通道,此時的通道長度變為3。

阻塞條件

帶緩衝通道在很多特性上和無緩衝通道是類似的。無緩衝通道可以看作是長度永遠為0的帶緩衝通道。因此根據這個特性,帶緩衝通道在下面列舉的情況下依然會發生阻塞:

帶緩衝通道被填滿時,嘗試再次傳送資料時發生阻塞。

帶緩衝通道為空時,嘗試接收資料時發生阻塞。

為什麼go語言對通道要限制長度而不提供無限長度的通道?

我們知道通道(channel)是在兩個goroutine間通訊的橋梁。使用goroutine的**必然有一方提供資料,一方消費資料。當提供資料一方的資料供給速度大於消費方的資料處理速度時,如果通道不限制長度,那麼記憶體將不斷膨脹直到應用崩潰。因此,限制通道的長度有利於約束資料提供方的供給速度,供給資料量必須在消費方處理量+通道長度的範圍內,才能正常地處理資料。

go語言通道插入0 Go 語言通道

51reboot 運維開發 golang 課程 k8s 課程 python 自動化高階課程 python 基礎實戰課程 運維前端課程 課程試聽預約請掃碼 原子函式和互斥函式都能工作,但是依靠它們都不會讓編寫併發程式變得更簡單,更不容易出錯,或者更有趣。在 go 語言裡,你可以使用通道來傳送和接收需要...

go語言通道插入0 Go語言之通道

所以在多個goroutine併發中,我們不僅可以通過原子函式和互斥鎖保證對共享資源的安全訪問,消除競爭的狀態,還可以通過使用通道,在多個goroutine傳送和接受共享的資料,達到資料同步的目的。通道,它有點像在兩個routine之間架設的管道 乙個goroutine可以往這個管道裡塞資料,另外乙個...

go語言通道插入0 Go 語言的併發性

昨天,我在 quora 上回答了乙個關於 go 語言併發模型的問題。現在,我覺得我還想再多說些什麼!併發性是 go 語言中最強大的特性之一。許多人討論了這個話題,從非常簡單到過於複雜的都有。今天,我也來說說我的看法。go 語言的併發性是一種思維方式而不僅僅是乙個語法。為了利用 go 的強大功能,你需...