原文鏈接:Go語言第十一課 並發(三)Channel緩存與阻塞
Channel的緩存
前面介紹過channel的創建方法:
channel_test := make(chan string)
其實它完整的寫法應該是:
channel_test := make(chan string,0)
這種容量為0的channel就是無緩存channel。對應地,我們也可以創建有緩存channel
channel_test := make(chan string,1)
無緩存channel
channel是否有緩存最根本的不同是阻塞策略的不同。
無緩存的channel會在讀寫兩端產生阻塞即:
當對一個無緩存的channel讀時,若數據尚未到達,則讀協程阻塞;當對一個無緩存的channel寫時,若數據尚未消費,則寫協程阻塞。
基於此,無緩存的channel也成為同步channel
需要特別注意的是,當數據尚未被消費時,接收者接收數據發生在喚醒發送者協程之前!
有緩存channel
帶緩存的channel實際上是一個阻塞隊列。對隊列的寫總發生在隊尾,隊列滿時寫協程阻塞;對隊列的讀總發生在隊尾,隊列空時讀協程阻塞。
內置函數cap(channel)可以讀取隊列的總長度。
內置隊列len(channel)可以讀取隊列的有效長度(已使用長度)。
有緩存的channel的最大意義在於生產和消費可以解耦。
協程泄漏
協程永遠阻塞,無法退出。即協程泄漏。協程的泄漏無法被自動回收,所以要極力避免!要確保每個協程都可以正常退出。