日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

go io.reader 多次读取_Go 经典入门系列 24:Select

發布時間:2024/9/27 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go io.reader 多次读取_Go 经典入门系列 24:Select 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
點擊上方藍色“Go語言中文網”關注,每天一起學 Go

歡迎來到 Golang 系列教程[1]的第 24 篇。

什么是 select?

select 語句用于在多個發送/接收信道操作中進行選擇。select 語句會一直阻塞,直到發送/接收操作準備就緒。如果有多個信道操作準備完畢,select 會隨機地選取其中之一執行。該語法與 switch 類似,所不同的是,這里的每個 case 語句都是信道操作。我們好好看一些代碼來加深理解吧。

示例

package?main

import?(
????"fmt"
????"time"
)

func?server1(ch?chan?string)?{
????time.Sleep(6?*?time.Second)
????ch?"from?server1"
}
func?server2(ch?chan?string)?{
????time.Sleep(3?*?time.Second)
????ch?"from?server2"

}
func?main()?{
????output1?:=?make(chan?string)
????output2?:=?make(chan?string)
????go?server1(output1)
????go?server2(output2)
????select?{
????case?s1?:=?????????fmt.Println(s1)
????case?s2?:=?????????fmt.Println(s2)
????}
}

在線運行程序[2]

在上面程序里,server1 函數(第 8 行)休眠了 6 秒,接著將文本 from server1 寫入信道 ch。而 server2 函數(第 12 行)休眠了 3 秒,然后把 from server2 寫入了信道 ch。

而 main 函數在第 20 行和第 21 行,分別調用了 server1 和 server2 兩個 Go 協程。

在第 22 行,程序運行到了 select 語句。select 會一直發生阻塞,除非其中有 case 準備就緒。在上述程序里,server1 協程會在 6 秒之后寫入 output1 信道,而server2 協程在 3 秒之后就寫入了 output2 信道。因此 select 語句會阻塞 3 秒鐘,等著 server2 向 output2 信道寫入數據。3 秒鐘過后,程序會輸出:

from?server2

然后程序終止。

select 的應用

在上面程序中,函數之所以取名為 server1 和 server2,是為了展示 select 的實際應用。

假設我們有一個關鍵性應用,需要盡快地把輸出返回給用戶。這個應用的數據庫復制并且存儲在世界各地的服務器上。假設函數 server1 和 server2 與這樣不同區域的兩臺服務器進行通信。每臺服務器的負載和網絡時延決定了它的響應時間。我們向兩臺服務器發送請求,并使用 select 語句等待相應的信道發出響應。select 會選擇首先響應的服務器,而忽略其它的響應。使用這種方法,我們可以向多個服務器發送請求,并給用戶返回最快的響應了。:)

默認情況

在沒有 case 準備就緒時,可以執行 select 語句中的默認情況(Default Case)。這通常用于防止 select 語句一直阻塞。

package?main

import?(
????"fmt"
????"time"
)

func?process(ch?chan?string)?{
????time.Sleep(10500?*?time.Millisecond)
????ch?"process?successful"
}

func?main()?{
????ch?:=?make(chan?string)
????go?process(ch)
????for?{
????????time.Sleep(1000?*?time.Millisecond)
????????select?{
????????case?v?:=?????????????fmt.Println("received?value:?",?v)
????????????return
????????default:
????????????fmt.Println("no?value?received")
????????}
????}

}

在線運行程序[3]

上述程序中,第 8 行的 process 函數休眠了 10500 毫秒(10.5 秒),接著把 process successful 寫入 ch 信道。在程序中的第 15 行,并發地調用了這個函數。

在并發地調用了 process 協程之后,主協程啟動了一個無限循環。這個無限循環在每一次迭代開始時,都會先休眠 1000 毫秒(1 秒),然后執行一個 select 操作。在最開始的 10500 毫秒中,由于 process 協程在 10500 毫秒后才會向 ch 信道寫入數據,因此 select 語句的第一個 case(即 case v := )并未就緒。所以在這期間,程序會執行默認情況,該程序會打印 10 次 no value received。

在 10.5 秒之后,process 協程會在第 10 行向 ch 寫入 process successful。現在,就可以執行 select 語句的第一個 case 了,程序會打印 received value: process successful,然后程序終止。該程序會輸出:

no?value?received
no?value?received
no?value?received
no?value?received
no?value?received
no?value?received
no?value?received
no?value?received
no?value?received
no?value?received
received?value:??process?successful

死鎖與默認情況

package?main

func?main()?{
????ch?:=?make(chan?string)
????select?{
????case?????}
}

在線運行程序[4]

上面的程序中,我們在第 4 行創建了一個信道 ch。我們在 select 內部(第 6 行),試圖讀取信道 ch。由于沒有 Go 協程向該信道寫入數據,因此 select 語句會一直阻塞,導致死鎖。該程序會觸發運行時 panic,報錯信息如下:

fatal?error:?all?goroutines?are?asleep?-?deadlock!

goroutine?1?[chan?receive]:
main.main()
????/tmp/sandbox416567824/main.go:6?+0x80

如果存在默認情況,就不會發生死鎖,因為在沒有其他 case 準備就緒時,會執行默認情況。我們用默認情況重寫后,程序如下:

package?main

import?"fmt"

func?main()?{
????ch?:=?make(chan?string)
????select?{
????case?????default:
????????fmt.Println("default?case?executed")
????}
}

在線運行程序[5]

以上程序會輸出:

default?case?executed

如果 select 只含有值為 nil 的信道,也同樣會執行默認情況。

package?main

import?"fmt"

func?main()?{
????var?ch?chan?string
????select?{
????case?v?:=?????????fmt.Println("received?value",?v)
????default:
????????fmt.Println("default?case?executed")

????}
}

在線運行程序[6]

在上面程序中,ch 等于 nil,而我們試圖在 select 中讀取 ch(第 8 行)。如果沒有默認情況,select 會一直阻塞,導致死鎖。由于我們在 select 內部加入了默認情況,程序會執行它,并輸出:

default?case?executed

隨機選取

當 select 由多個 case 準備就緒時,將會隨機地選取其中之一去執行。

package?main

import?(
????"fmt"
????"time"
)

func?server1(ch?chan?string)?{
????ch?"from?server1"
}
func?server2(ch?chan?string)?{
????ch?"from?server2"

}
func?main()?{
????output1?:=?make(chan?string)
????output2?:=?make(chan?string)
????go?server1(output1)
????go?server2(output2)
????time.Sleep(1?*?time.Second)
????select?{
????case?s1?:=?????????fmt.Println(s1)
????case?s2?:=?????????fmt.Println(s2)
????}
}

在線運行程序[7]

在上面程序里,我們在第 18 行和第 19 行分別調用了 server1 和 server2 兩個 Go 協程。接下來,主程序休眠了 1 秒鐘(第 20 行)。當程序控制到達第 21 行的 select 語句時,server1 已經把 from server1 寫到了 output1 信道上,而 server2 也同樣把 from server2 寫到了 output2 信道上。因此這個 select 語句中的兩種情況都準備好執行了。如果你運行這個程序很多次的話,輸出會是 from server1 或者 from server2,這會根據隨機選取的結果而變化。

請在你的本地系統上運行這個程序,獲得程序的隨機結果。因為如果你在 playground 上在線運行的話,它的輸出總是一樣的,這是由于 playground 不具有隨機性所造成的。

這下我懂了:空 select

package?main

func?main()?{
????select?{}
}

在線運行程序[8]

你認為上面代碼會輸出什么?

我們已經知道,除非有 case 執行,select 語句就會一直阻塞著。在這里,select 語句沒有任何 case,因此它會一直阻塞,導致死鎖。該程序會觸發 panic,輸出如下:

fatal?error:?all?goroutines?are?asleep?-?deadlock!

goroutine?1?[select?(no?cases)]:
main.main()
????/tmp/sandbox299546399/main.go:4?+0x20

本教程到此結束。祝你愉快。

上一教程 - 緩沖信道和工作池

下一教程 - Mutex[9]



推薦閱讀

  • Go 經典入門系列 23:緩沖信道和工作池

福利我為大家整理了一份從入門到進階的Go學習資料禮包,包含學習建議:入門看什么,進階看什么。關注公眾號 「polarisxu」,回復 ebook獲取;還可以回復「進群」,和數萬 Gopher 交流學習。

總結

以上是生活随笔為你收集整理的go io.reader 多次读取_Go 经典入门系列 24:Select的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧洲精品一区二区三区 | 国语播放老妇呻吟对白 | 国产亚洲高清视频 | av免费片 | 亚洲国产精品久久 | 国产视频一区在线播放 | 动漫美女隐私无遮挡 | 国产午夜精品无码一区二区 | 朝桐光在线观看 | 亚洲日本护士毛茸茸 | 女人张开腿让男人桶爽 | 人妻互换一二三区激情视频 | 97超碰人人看 | 69超碰| 五月天丁香在线 | 一区二区国产在线 | 少妇高潮一区二区三区99小说 | 久天堂 | 91视频在线免费 | 黄色一级片 | 精品91av | 69免费| av永久免费 | 欧美特级黄 | 日韩黄色av| 91精品视频网 | 中文字幕一区二区免费 | 日韩欧美三级 | 女人的洗澡毛片毛多 | 中文字幕一区2区3区 | www.四虎精品 | 久久久国产精品免费 | 亚州av | 麻豆av一区二区三区久久 | 黄色三级小视频 | 日韩中文字幕亚洲精品欧美 | а√天堂www在线天堂小说 | 美女隐私免费看 | av资源站最新av | 放荡闺蜜高h苏桃情事h | 亚洲一区二区在线观看视频 | 欧美youjizz| 女人18毛片一区二区三区 | 日本午夜啪啪 | 韩国黄色网址 | 国产成人在线看 | 中文字幕人成 | 男女爽爽 | 欧美性受xxxx白人性爽 | 欧美乱插 | 国产在线拍揄自揄拍无码视频 | 国产粉嫩在线观看 | 青草视频在线观看免费 | 欧美激情影音先锋 | 欧洲a级片 | 亚洲不卡电影 | 男生插女生网站 | 欧美精品一区在线 | 一级成人免费 | 自拍欧美亚洲 | 欧美日韩一区不卡 | 欧美激情影院 | 免费看黄色a级片 | 影视av| 亚洲蜜臀av乱码久久精品蜜桃 | 91精品视频免费在线观看 | 强公把我次次高潮hd | 丰满大爆乳波霸奶 | 超污视频软件 | 精品国产99久久久久久宅男i | 精品中文字幕一区 | 热热av | 深夜精品视频 | 国产免费视频一区二区三区 | 日韩一区二区免费播放 | 奇米91| 秋霞无码一区二区 | 不卡av免费在线观看 | 日本a级c片免费看三区 | 99视频99| 成人福利av | 亚洲欧美日韩不卡 | 中文字幕视频免费观看 | 91av免费在线观看 | 黑人导航 | 国产精品自拍网 | 丁香社区五月天 | 久草精品视频在线观看 | 日本十八禁视频无遮挡 | aa视频网站| 天堂在线播放 | 另类激情 | 高潮疯狂过瘾粗话对白 | 自拍偷拍亚洲欧美 | 免费荫蒂添的好舒服视频 | 五月天丁香久久 | 亚洲xx网| 国产精品毛片久久 | 欧美精品一级二级 |