go之無緩沖channel(通道)和有緩沖channel(通道)


channel
我們先來看一下通道的解釋:
channel是Go語言中的一個核心類型,可以把它看成管道。並發核心單元通過它就可以發送或者接收數據進行通訊,這在一定程度上又進一步降低了編程的難度。
channel是一個數據類型,主要用來解決go程的同步問題以及協程之間數據共享(數據傳遞)的問題。
goroutine運行在相同的地址空間,因此訪問共享內存必須做好同步。goroutine 奉行通過通信來共享內存,而不是共享內存來通信。
引用類型 channel可用於多個 goroutine 通訊。其內部實現了同步,確保並發安全。


定義channel和使用
和map類似,channel也一個對應make創建的底層數據結構的引用。
當我們復制一個channel或用於函數參數傳遞時,我們只是拷貝了一個channel引用,因此調用者和被調用者將引用同一個channel對象。和其它的引用類型一樣,channel的零值也是nil。
定義一個channel時,也需要定義發送到channel的值的類型。channel可以使用內置的make()函數來創建:
我們先來看一段代碼

package main
import "fmt"
func main(){
ch:=make(chan int) //這里就是創建了一個channel,這是無緩沖管道注意
go func(){ //創建子go程
for i:=0;i<6;i++{
ch<-i //循環寫入管道
fmt.Println("寫入",i)
}
}()

for i:=0;i<6;i++{ //主go程
num:=<-ch //循環讀出管道
fmt.Println("讀出",num)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
我們先看一下運行結果再來看代碼:

我們在代碼中 先創建了一個匿名函數的子go程,和main的主go程一起爭奪cpu,但是我們在里面創建了一個管道,無緩沖管道有一個規則那就是必須讀寫同時操作才會有效果,如果只進行讀或者只進行寫那么會被阻塞,被暫時停頓等待另外一方的操作,在這里我們定義了一個容量為0的通道,這就是無緩沖通道,如下圖

無緩沖通道就是這樣,一次只能傳輸一個數據
總結一下就是無緩沖特性:
同一時刻,同時有 讀、寫兩端把持 channel。
如果只有讀端,沒有寫端,那么 “讀端”阻塞。
如果只有寫端,沒有讀端,那么 “寫端”阻塞。
讀channel: <- channel
寫channel: channel <- 數據

有緩沖channel
如圖所示:

. 在第 1 步,右側的 goroutine 正在從通道接收一個值。
在第 2 步,右側的這個 goroutine獨立完成了接收值的動作,而左側的 goroutine 正在發送一個新值到通道里。
在第 3 步,左側的goroutine 還在向通道發送新值,而右側的 goroutine 正在從通道接收另外一個值。這個步驟里的兩個操作既不是同步的,也不會互相阻塞。
最后,在第 4 步,所有的發送和接收都完成,而通道里還有幾個值,也有一些空間可以存更多的值。
有緩沖通道就是圖中所示,一方可以寫入很多數據,不用等對方的操作,而另外一方也可以直接拿出數據,不需要等對方寫,但是注意一點(如果寫入的一方把channel寫滿了,那么如果要繼續寫就要等對方取數據后才能繼續寫入,這也是一種阻塞,讀出數據也是一樣,如果里面沒有數據則不能取,就要等對方寫入),而有緩沖channel定義也比較簡單

ch:=make(chan int,10)//chan int 只能寫入讀入int類型的數據,10代表容量為10.
1
這里用了自動推導類型來聲明了一個有緩沖的channel
總結起來就是:
channel 中自帶緩沖區。創建時可以指定緩沖區的大小。
w:直到緩沖區被填滿后,寫端才會阻塞。
r:緩沖區被讀空,讀端才會阻塞。
len:代表緩沖區中,剩余元素個數,
cap:代表緩沖區的容量。
在這里可以舉個小小的例子來解釋一下有緩沖channel和無緩沖channel
同步通信: 數據發送端,和數據接收端,必須同時在線。 —— 無緩沖channel
打電話。打電話只有等對方接收才會通,要不然只能阻塞

異步通信:數據發送端,發送完數據,立即返回。數據接收端有可能立即讀取,也可能延遲處理。 —— 有緩沖channel 不用等對方接受,只需發送過去就行
發信息。短信。
是不是很形象呢
下一節將講解一下channel常見的陷阱以及關閉channel


————————————————
版權聲明:本文為CSDN博主「sgsgy5」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/sgsgy5/article/details/82054902


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM