【鏈塊技術37期】區塊鏈技術語言(二十八)——Go語言併發編程(下)

原文鏈接:區塊鏈技術語言(二十八):Go語言併發編程(下)

 

本節緊接上一節的內容,主要介紹channel中的有緩衝channel、單方向的channel、定時器,以及select語句在channel中的應用。

3.4 有緩衝的channel

3.4.1 概述

有緩衝的通道(buffered channel)是一種在被接收前能存儲一個或者多個值的通道。這種類型的通道並不強制要求goroutine之間必須同時完成發送和接收,通道會阻塞發送和接收動作的條件也不同:只有在通道中沒有要接收的值時,接收動作纔會阻塞;只有在通道沒有可用緩衝區容納被髮送的值時,發送動作纔會阻塞。

有緩衝的通道和無緩衝的通道之間的最大不同在於:無緩衝通道保證發送和接收的goroutine會在同一時間進行數據交換;有緩衝的通道沒有這種保證。

圖2通過示意圖分析了多個goroutine利用有緩衝通道來共享一個值:

a. 第1步,右側的goroutine正在從通道中接收一個值;

b. 第2步,右側的這個goroutine獨立完成了接收值的動作,而左側的goroutine正在發送一個新值到通道里;

c. 第3步,左側的goroutine向通道發送新值,右側的goroutine正在從通道接收另外一個值。這個步驟裏的兩個操作既不是同步的,也不會互相阻塞;

d. 第4步,所有的發送和接收都完成,而通道里還有幾個值,也有一些空間可以存更多的值。

3.4.2 有緩衝的channel的創建

如果給定了一個緩衝區容量,通道就是異步的。只要緩衝區有未使用空間用於發送數據,或者還包含可以接收的數據,那麼其通信就會無阻塞地進行。有緩衝的channel創建格式如下:

示例代碼:

3.5 單方向的channel

3.5.1 概述

channel默認雙向。既可以向channel裏發送數據,也可以從channel裏接收數據。但是,要使channel作爲參數傳遞且被單向使用,即只向該channel發送數據,或此channel只接收數據,那麼需要對此channel指定方向。

3.5.2 單向channel變量的聲明

單向channel變量有兩種:一種是隻能向channel裏發送數據的變量,另一種是隻能從channel裏接收數據的變量。

單向channel變量的聲明格式如表2。

注:a. chan<-表示把數據寫入管道;

     b. <-chan表示將數據從管道中讀取。

3.5.3 channel的轉換

普通的channel可以隱式地轉換爲單向的channel,只接收數據或只發送數據;但是單向的channel不能轉換爲普通的channel。

示例代碼:

四、select

4.1 select語法結構

Go語言關鍵字select可以監聽channel上的數據流動。

它的用法與switch語句類似,由select開始一個新的選擇塊,每個選擇條件由case語句來描述。與switch語句可以選擇任何可使用相等比較的條件相比, select有比較多的限制,其中最大的一條限制就是每個case語句裏必須是一個IO(輸入/輸出)操作,它的語法結構如下:

4.2 select語句執行順序

在select語句中,Go語言按順序從頭至尾評估每一個發送和接收的語句:

如果其中任意一條語句可以繼續執行(即沒有被阻塞),那麼就從那些可以執行的語句中任意選擇一條來使用。

如果沒有一條語句可以執行(即所有的通道都被阻塞),那麼有兩種可能的情況:第一,如果有default語句,那麼就會執行default語句,同時程序的執行會從select語句後的語句中恢復;第二,如果沒有default語句,那麼select語句將被阻塞,直到至少有一個case語句可以進行下去。

在沒有case準備就緒時,可以執行select語句中的default語句,這通常用於防止select語句一直阻塞。

4.3 在select語句中設置超時

當goroutine阻塞時,爲避免整個程序進入阻塞,可以在select語句設置超時,具體通過如下方式實現:

示例如下:

參考資料:

https://www.cnblogs.com/tangchuanyang/p/5553434.html

http://www.flysnow.org/2017/04/11/go-in-action-go-goroutine.html

https://studygolang.com/articles/3028

 

本文完,獲取更多資訊,敬請關注區塊鏈工程師。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章