日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

golang select default continue_Go并发(四):select篇

發(fā)布時(shí)間:2024/9/27 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang select default continue_Go并发(四):select篇 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
轉(zhuǎn)載于公眾號(hào):灰子學(xué)技術(shù)
原文鏈接:https://mp.weixin.qq.com/s/nJRVbhRQCgWHR1eHSfBpFA

一、前言介紹:

對(duì)于Go語(yǔ)言并發(fā)通訊,是使用的協(xié)程goroutine,而協(xié)程之間的通訊采用的是channel。但是channel不管是有緩存的,還是無(wú)緩存的都會(huì)有阻塞的情況出現(xiàn),只不過(guò)無(wú)緩存的阻塞會(huì)更加頻繁。而協(xié)程長(zhǎng)時(shí)間阻塞了之后,Go語(yǔ)言本身又沒(méi)有提供這種超時(shí)的解決機(jī)制,所以開(kāi)發(fā)者需要自己考慮實(shí)現(xiàn)這種超時(shí)機(jī)制。這種超時(shí)機(jī)制在Go語(yǔ)言中則是使用select來(lái)解決的。

相關(guān)的背景知識(shí):

1.Go語(yǔ)言并發(fā)篇(一):之go語(yǔ)句篇:https://mp.weixin.qq.com/s/FD-MP9r5sEn1QYRAYZE_4g
2.Go語(yǔ)言之goroutine的調(diào)度原理: https://mp.weixin.qq.com/s/hTgIyJN7p-wrDfLj1bP1wQ
3.Go并發(fā)之channel篇:https://mp.weixin.qq.com/s/PIb-gGBootc6581pHhi5ew

二、Select內(nèi)容介紹

我們先來(lái)看幾個(gè)問(wèn)題, select是什么?它都有那些特性?

語(yǔ)法定義:
select是Go語(yǔ)言中的一個(gè)控制語(yǔ)句,它有select,case, default共同構(gòu)成,與switch的書(shū)寫(xiě)方式類似。
select只用來(lái)操作的channel的讀寫(xiě)操作。
(備注:golang 的 select 本質(zhì)上,就是監(jiān)聽(tīng) IO 操作,當(dāng) IO 操作發(fā)生時(shí),觸發(fā)相應(yīng)的動(dòng)作。也是常用的多路復(fù)用的一種,例如poll, epoll(這個(gè)會(huì)在另外一個(gè)帖子中介紹), select )

例子:

select 的特性:
1. 如果只有一個(gè) case 語(yǔ)句評(píng)估通過(guò),那么就執(zhí)行這個(gè)case里的語(yǔ)句
2. 如果有多個(gè) case 語(yǔ)句評(píng)估通過(guò),那么通過(guò)偽隨機(jī)的方式隨機(jī)選一個(gè)
3.如果 default 外的 case 語(yǔ)句都沒(méi)有通過(guò)評(píng)估,那么執(zhí)行 default 里的語(yǔ)句
4.如果沒(méi)有 default,那么 代碼塊會(huì)被阻塞,直到有一個(gè) case 通過(guò)評(píng)估;否則一直阻塞

特性1: select正常case能夠評(píng)估通過(guò)的例子:

?特性4: 沒(méi)有default分支,select被阻塞住的例子:

對(duì)比特性1,會(huì)發(fā)現(xiàn),select在探測(cè)不到case是接收c1數(shù)據(jù)的情況下,會(huì)阻塞在哪里,不會(huì)打印"go end!"

特性3: 有default的例子:

select存在default的話,在case不命中的情況下,會(huì)直接進(jìn)入default分支,協(xié)程一樣會(huì)結(jié)束,不會(huì)阻塞住。

特性2: 多個(gè)case 同時(shí)滿足的情況,會(huì)隨機(jī)選擇一個(gè)case

?通過(guò)輸出我們可以看出來(lái),盡管channel c1和c2基本是同時(shí)寫(xiě)的數(shù)據(jù)到channel中,但是select選擇了c2,忽略了c1。

三、select的應(yīng)用場(chǎng)景

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

select的應(yīng)用場(chǎng)景都有那些,為什么我們需要select?

場(chǎng)景一:實(shí)現(xiàn)非阻塞讀寫(xiě)操作。

根據(jù)select的特性3(如果 default 外的 case 語(yǔ)句都沒(méi)有通過(guò)評(píng)估,那么執(zhí)行 default 里的語(yǔ)句), 我們可以實(shí)現(xiàn)非阻塞的讀寫(xiě)操作。

這種情況,一般是發(fā)生在服務(wù)器在給用戶推送數(shù)據(jù)之后,不希望用戶一直阻塞在讀操作上面。代碼實(shí)例參考特性3的例子,我們利用default來(lái)跳過(guò)這個(gè)阻塞過(guò)程。

場(chǎng)景二: 為請(qǐng)求設(shè)置超時(shí)時(shí)間。

這一個(gè)場(chǎng)景也就是前言介紹里面提到的協(xié)程通訊時(shí)候,長(zhǎng)時(shí)間收不到讀寫(xiě)操作,導(dǎo)致協(xié)程一直被阻塞的情況,而超時(shí)機(jī)制則是一個(gè)很常規(guī)的操作。我們來(lái)看下例子:

1.復(fù)現(xiàn)channel阻塞的例子:

?2.超時(shí)處理的例子:

?例子1,因?yàn)閏hannel中沒(méi)有數(shù)據(jù)可讀,導(dǎo)致協(xié)程一直阻塞住,并沒(méi)有g(shù)o end的日志打印出來(lái)。

例子2, 雖然channel 中依然沒(méi)有數(shù)據(jù)可讀,但是我們實(shí)現(xiàn)了超時(shí)機(jī)制,在2s超時(shí)之后,select會(huì)觸發(fā)超時(shí)相關(guān)的channel,進(jìn)而結(jié)束協(xié)程go的阻塞,打印出go end日志。

場(chǎng)景三: 調(diào)度協(xié)程,控制其他協(xié)程的退出或者完成

在并發(fā)程序中,通常 main goroutine 將任務(wù)分給其它 goroutine 去完成,而自身只是起到調(diào)度作用。這種情況下,main goroutine無(wú)法知道 其它goroutine 任務(wù)是否完成,此時(shí)我們需要 done channel來(lái)協(xié)助完成。

例子為:

不實(shí)用done channel的方式,會(huì)發(fā)現(xiàn)main的goroutinue并不會(huì)等待其他的goroutine結(jié)束之后,才結(jié)束,也不知道其他的goroutiue何時(shí)結(jié)束。

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

?備注:對(duì)于select的實(shí)現(xiàn)機(jī)制,這個(gè)在后面的文章中介紹。

Go Channel 詳解: https://colobu.com/2016/04/14/Golang-Channels/

Go語(yǔ)言并發(fā)模型:使用 select:https://segmentfault.com/a/1190000006815341

灰子學(xué)技術(shù),歡迎關(guān)注,點(diǎn)評(píng),相互學(xué)習(xí)。

?

總結(jié)

以上是生活随笔為你收集整理的golang select default continue_Go并发(四):select篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。