第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

選定組中的通道在指定時間內(nèi)沒有接收到信號時跳出循環(huán)

選定組中的通道在指定時間內(nèi)沒有接收到信號時跳出循環(huán)

Go
Qyouu 2023-05-08 15:28:50
當且僅當我在特定時間段內(nèi)我的 select 語句正在偵聽的任何通道上都沒有收到任何信號時,我該如何跳出包含 select 語句的慣用 Go for 循環(huán)。讓我用一個例子來加強這個問題。設(shè)置:假設(shè)我有一個var listenCh <-chan string正在收聽的頻道。讓我們假設(shè)其他一些 go 例程(不在我們的控制范圍內(nèi))在此通道上發(fā)送不同的字符串。我對給定的字符串進行一些處理,然后在listenCh.要求:我想在 上的兩個連續(xù)信號之間最多等待 10 秒(精度不重要)listenCh,然后再關(guān)閉我的操作(永久中斷 for 循環(huán))。代碼存根:func doingSomething(listenCh <-chan string) {  var mystr string  for {    select {      case mystr <-listenCh:        //dosomething      case /*more than 10 seconds since last signal on listenCh*/:        return    }  }}我將如何以最有效的方式實現(xiàn)我的要求。通常的退出通道技術(shù)time.After(time.Duration)似乎在一個循環(huán)后不會重置,因此即使有連續(xù)的值流,整個程序也會在 10 秒內(nèi)關(guān)閉。我在 SO 上找到了問題的變體(但不是我想要的),但我看到的沒有一個能回答我的特定用例。
查看完整描述

1 回答

?
心有法竹

TA貢獻1866條經(jīng)驗 獲得超5個贊

前言:使用time.Timer是推薦的方式,time.After()這里的使用只是為了演示和推理。請使用第二種方法。


使用time.After()(不推薦這樣做)

如果你放入time.After()case 分支,那將在每次迭代中“重置”,因為每次都會返回一個新頻道,這樣就可以了:

func doingSomething(listenCh <-chan string) {

? ? for {

? ? ? ? select {

? ? ? ? case mystr := <-listenCh:

? ? ? ? ? ? log.Println("Received", mystr)

? ? ? ? case <-time.After(1 * time.Second):

? ? ? ? ? ? log.Println("Timeout")

? ? ? ? ? ? return

? ? ? ? }

? ? }

}

(我在 Go Playground 上使用 1 秒超時來提高可測試性。)


我們可以這樣測試它:


ch := make(chan string)

go func() {

? ? for i := 0; i < 3; i++ {

? ? ? ? ch <- fmt.Sprint(i)

? ? ? ? time.Sleep(500 * time.Millisecond)

? ? }

}()

doingSomething(ch)

輸出(在Go Playground上嘗試):


2009/11/10 23:00:00 Received 0

2009/11/10 23:00:00 Received 1

2009/11/10 23:00:01 Received 2

2009/11/10 23:00:02 Timeout

使用time.Timer(推薦方案)

如果從通道接收的速率很高,這可能會有點浪費資源,因為在后臺創(chuàng)建并使用了一個新計時器,time.After()它不會神奇地停止并在不再需要時立即收集垃圾如果您在超時前從通道收到一個值。

time.Timer一個對資源更友好的解決方案是在循環(huán)之前創(chuàng)建一個循環(huán),如果在超時之前收到一個值,則將其重置。

這就是它的樣子:

func doingSomething(listenCh <-chan string) {

? ? d := 1 * time.Second

? ? t := time.NewTimer(d)

? ? for {

? ? ? ? select {

? ? ? ? case mystr := <-listenCh:

? ? ? ? ? ? log.Println("Received", mystr)

? ? ? ? ? ? if !t.Stop() {

? ? ? ? ? ? ? ? <-t.C

? ? ? ? ? ? }

? ? ? ? ? ? t.Reset(d)

? ? ? ? case <-t.C:

? ? ? ? ? ? log.Println("Timeout")

? ? ? ? ? ? return

? ? ? ? }

? ? }

}

測試和輸出是一樣的。在Go Playground試試這個。



查看完整回答
反對 回復 2023-05-08
  • 1 回答
  • 0 關(guān)注
  • 141 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號