91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go并發中select的示例分析

發布時間:2021-11-17 17:56:01 來源:億速云 閱讀:302 作者:小新 欄目:大數據

這篇文章給大家分享的是有關go并發中select的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

一、前言介紹:

對于Go語言并發通訊,是使用的協程goroutine,而協程之間的通訊采用的是channel。但是channel不管是有緩存的,還是無緩存的都會有阻塞的情況出現,只不過無緩存的阻塞會更加頻繁。而協程長時間阻塞了之后,Go語言本身又沒有提供這種超時的解決機制,所以開發者需要自己考慮實現這種超時機制。這種超時機制在Go語言中則是使用select來解決的。

相關的背景知識:

1.Go語言并發篇(一):之go語句篇:https://mp.weixin.qq.com/s/FD-MP9r5sEn1QYRAYZE_4g

2.Go語言之goroutine的調度原理:https://mp.weixin.qq.com/s/hTgIyJN7p-wrDfLj1bP1wQ

3.Go并發之channel篇:https://mp.weixin.qq.com/s/PIb-gGBootc6581pHhi5ew

二、Select內容介紹

我們先來看幾個問題, select是什么?它都有哪n些特性?

語法定義:

select是Go語言中的一個控制語句,它有select,case, default共同構成,與switch的書寫方式類似。

select只用來操作的channel的讀寫操作。

(備注:golang 的 select 本質上,就是監聽 IO 操作,當 IO 操作發生時,觸發相應的動作。也是常用的多路復用的一種,例如poll, epoll(這個會在另外一個帖子中介紹), select )

例子:

go并發中select的示例分析

select 的特性:
1. 如果只有一個 case 語句評估通過,那么就執行這個case里的語句

2. 如果有多個 case 語句評估通過,那么通過偽隨機的方式隨機選一個

3.如果 default 外的 case 語句都沒有通過評估,那么執行 default 里的語句

4.如果沒有 default,那么 代碼塊會被阻塞,直到有一個 case 通過評估;否則一直阻塞

特性1:  select正常case能夠評估通過的例子:

go并發中select的示例分析

特性4: 沒有default分支,select被阻塞住的例子:

go并發中select的示例分析

對比特性1,會發現,select在探測不到case是接收c1數據的情況下,會阻塞在哪里,不會打印"go end!"

特性3: 有default的例子:

go并發中select的示例分析

select存在default的話,在case不命中的情況下,會直接進入default分支,協程一樣會結束,不會阻塞住。

特性2: 多個case 同時滿足的情況,會隨機選擇一個case

go并發中select的示例分析

通過輸出我們可以看出來,盡管channel c1和c2基本是同時寫的數據到channel中,但是select選擇了c2,忽略了c1。

三、select的應用場景

 在看完了select的特性之后,筆者知道了channel的使用方式。可是到底什么時候使用select呢?于是筆者便問了自己另外一個問題。

select的應用場景都有哪些,為什么我們需要select?

場景一:實現非阻塞讀寫操作。

根據select的特性3(如果 default 外的 case 語句都沒有通過評估,那么執行 default 里的語句), 我們可以實現非阻塞的讀寫操作。

這種情況,一般是發生在服務器在給用戶推送數據之后,不希望用戶一直阻塞在讀操作上面。代碼實例參考特性3的例子,我們利用default來跳過這個阻塞過程。

場景二: 為請求設置超時時間。

這一個場景也就是前言介紹里面提到的協程通訊時候,長時間收不到讀寫操作,導致協程一直被阻塞的情況,而超時機制則是一個很常規的操作。我們來看下例子:

1.復現channel阻塞的例子:

go并發中select的示例分析

2.超時處理的例子:

go并發中select的示例分析

例子1,因為channel中沒有數據可讀,導致協程一直阻塞住,并沒有go end的日志打印出來。

例子2, 雖然channel 中依然沒有數據可讀,但是我們實現了超時機制,在2s超時之后,select會觸發超時相關的channel,進而結束協程go的阻塞,打印出go end日志。

場景三: 調度協程,控制其他協程的退出或者完成

在并發程序中,通常 main goroutine 將任務分給其它 goroutine 去完成,而自身只是起到調度作用。這種情況下,main goroutine無法知道 其它goroutine 任務是否完成,此時我們需要 done channel來協助完成。

例子為:

不實用done channel的方式,會發現main的goroutinue并不會等待其他的goroutine結束之后,才結束,也不知道其他的goroutiue何時結束。

go并發中select的示例分析

添加了done channel之后,main goroutinue可以等待其他的goroutinue結束之后,再結束。

go并發中select的示例分析

感謝各位的閱讀!關于“go并發中select的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南开区| 沂水县| 萨嘎县| 平定县| 仙居县| 滦平县| 平凉市| 唐河县| 城步| 沙洋县| 万载县| 临海市| 文山县| 三穗县| 玉田县| 泸溪县| 枣庄市| 仁化县| 贺州市| 东城区| 江源县| 平果县| 青田县| 四子王旗| 常宁市| 洛阳市| 中阳县| 滦南县| 百色市| 玉山县| 大名县| 东莞市| 大安市| 乌拉特后旗| 宿松县| 满城县| 和平县| 阳原县| 清流县| 淳化县| 上栗县|