無緩沖channel與容量為1的channel的區別


有緩沖和無緩沖channel的聲明

下面簡要說明它們之間的區別,先聲明兩個channel分別有緩沖1和無緩沖:

c1 := make(chan int) // 無緩沖
c2 := make(chan int, 1) // 有緩沖

無緩沖的channel

下面討論一個簡單的場景:A向channel寫入一個int,B從channel讀走一個int,
對於c1,可以假設A和B是兩個goroutine,是兩個並發單位。代碼如下:

c1 <- 1   // A
<- c1     // B

重點來了:這里的A或B,無論誰先執行,誰都會阻塞以等待另一個goroutine執行,也就是說往里寫得等來讀的,從里讀得等來寫的。最重要的是,A和B對c1的讀寫是同步的,直觀的理解是A和B對c1的讀寫是同時發生的,當A對c1寫完了,則B從c1中就讀完了。這樣的特性可以用於做並發單位之間的同步操作,如果在A和B中對同一個無緩沖通道進行了讀寫,那么A和B一定會在讀寫的地方進行同步,誰先到誰阻塞等待另外一個。
綜上,如果在一個協程里寫這樣的代碼,一定會死鎖:

func main() {
	ch := make(chan int)
	ch <- 1
        <- ch
}

無緩沖的channel的讀寫者必須同時完成發送和接收,而不能串行,顯然單協程無法滿足。所以這里造成了循環等待,會死鎖。

緩沖為1的channel

我們依然繼續上面提到的簡單場景:A向channel寫入一個int,B從channel讀走一個int。還是一樣的代碼:

c2 <- 1   // A
<- c2     // B

這里和無緩沖通道不同的地方在於:有緩沖的通道並不強制channel的讀寫者必須同時完成發送和接收,讀者只會在沒有數據時阻塞,寫者只會在沒有可用容量時阻塞,這就有點像阻塞隊列了。


免責聲明!

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



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