一招教你無阻塞讀寫Golang channel

2021-09-19 22:23:22 字數 2225 閱讀 2481

無論是無緩衝通道,還是有緩衝通道,都存在阻塞的情況,教你一招再也不遇到channel阻塞的問題。

這篇文章會介紹,哪些情況會存在阻塞,以及如何使用select解決阻塞。

阻塞場景

阻塞場景共4個,有快取和無緩衝各2個。

無緩衝通道的特點是,傳送的資料需要被讀取後,傳送才會完成,它阻塞場景:

通道中無資料,但執行讀通道。

通道中無資料,向通道寫資料,但無協程讀取。

1// 場景1

2func readnodatafromnobufch()

1112// 場景2

13func writenobufch()

注:示例**中的output注釋代表函式的執行結果,每乙個函式都由於阻塞在通道操作而無法繼續向下執行,最後報了死鎖錯誤。

有快取通道的特點是,有快取時可以向通道中寫入資料後直接返回,快取中有資料時可以從通道中讀到資料直接返回,這時有快取通道是不會阻塞的,它阻塞的場景是:

通道的快取無資料,但執行讀通道。

通道的快取已經佔滿,向通道寫資料,但無協程讀。

1// 場景1

2func readnodatafrombufch()

1112// 場景2

13func writebufchbutfull()

使用select實現無阻塞讀寫

select是執行選擇操作的乙個結構,它裡面有一組case語句,它會執行其中無阻塞的那乙個,如果都阻塞了,那就等待其中乙個不阻塞,進而繼續執行,它有乙個default語句,該語句是永遠不會阻塞的,我們可以借助它實現無阻塞的操作。

下面示例**是使用select修改後的無緩衝通道和有緩衝通道的讀寫,以下函式可以直接通過main函式呼叫,其中的ouput的注釋是執行結果,從結果能看出,在通道不可讀或者不可寫的時候,不再阻塞等待,而是直接返回。

1// 無緩衝通道讀

2func readnodatafromnobufchwithselect() else

1011 // output:

12 // channel has no data

13}14

15// 有緩衝通道讀

16func readnodatafrombufchwithselect() else

2425 // output:

26 // channel has no data

27}28

29// select結構實現通道讀

30func readwithselect(ch chan int) (x int, err error)

37}38

39// 無緩衝通道寫

40func writenobufchwithselect() else

4748 // output:

49 // channel blocked, can not write

50}51

52// 有緩衝通道寫

53func writebufchbutfullwithselect() else

6263 // output:

64 // channel blocked, can not write

65}66

67// select結構實現通道寫

68func writechwithselect(ch chan int) error

使用select+超時改善無阻塞讀寫

使用default實現的無阻塞通道阻塞有乙個缺陷:當通道不可讀或寫的時候,會即可返回。實際場景,更多的需求是,我們希望,嘗試讀一會資料,或者嘗試寫一會資料,如果實在沒法讀寫,再返回,程式繼續做其它的事情。

使用定時器替代default可以解決這個問題。比如,我給通道讀寫資料的容忍時間是500ms,如果依然無法讀寫,就即刻返回,修改一下會是這樣:

1func readwithselect(ch chan int) (x int, err error) 

10}11

12func writechwithselect(ch chan int) error

21}

結果就會變成超時返回:

1read time out

2write time out

3read time out

4write time out

Golang併發 一招掌握無阻塞通道讀寫

介紹golang併發的模型寫了幾篇了,但一直沒有以channel為主題進行介紹,今天就給大家聊一聊channel,channel的基本使用非常簡單,想必大家都已了解,所以直接來個高階點的 介紹channel的阻塞情況,以及給你乙個必殺技,立馬解決阻塞問題,實用性高。無論是有快取通道 無緩衝通道都存在...

Golang通道的無阻塞讀寫的方法示例

無論是無緩衝通道,還是有緩衝通道,都存在阻塞的情況,但其實有些情況,我們並不想讀資料或者寫資料阻塞在那裡,有1個唯一的解決辦法,那就是使用select結構。這篇文章會介紹,哪些情況會存在阻塞,以及如何使用select解決阻塞。阻塞場景 阻塞場景共4個,有快取和無緩衝各2個。無緩衝通道的特點是,傳送的...

一招教你關閉瀏覽視窗

工作列預覽功能在windows7那個時候還是比較不錯的功能,但是現在在windows8或者10上就顯得有點沒啥用了,windows10把可以關閉的工作列預覽功能選項刪除了,滑鼠滑過後不僅會遮擋螢幕,要是磁碟效能不濟,卡頓跳幀是經常有的事。既然 設定 和 控制面板 中沒有,那就只好拿登錄檔開刀了。wi...