亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

使用sync.WaitGroup.wait時如何實現超時?

使用sync.WaitGroup.wait時如何實現超時?

Go
慕娘9325324 2021-11-29 16:52:45
我遇到過一種情況,我想跟蹤某個 goroutine 以在特定點上進行同步,例如在獲取所有 url 時。然后,我們可以將它們全部放置并按特定順序顯示。我認為這是障礙進來的。它是在go與sync.WaitGroup. 但是,在實際情況下,我們無法確保所有的 fetch 操作都會在短時間內成功。所以,我想wait在獲取操作時引入超時。我是新手Golang,所以有人可以給我一些建議嗎?我正在尋找的是這樣的:   wg := &sync.WaigGroup{}   select {   case <-wg.Wait():   // All done!   case <-time.After(500 * time.Millisecond):   // Hit timeout.   }我知道Wait不支持Channel。
查看完整描述

3 回答

?
慕桂英4014372

TA貢獻1871條經驗 獲得超13個贊

如果你想要的只是你的簡潔選擇,你可以通過生成一個調用方法并在完成后關閉/發送通道的例程來輕松地將阻塞功能轉換為通道。


done := make(chan struct{})

go func() {

   wg.Wait()

   close(done)

}()


select {

case <-done:

// All done!

case <-time.After(500 * time.Millisecond):

// Hit timeout.

}


查看完整回答
反對 回復 2021-11-29
?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

將您的結果發送到一個緩沖通道,足以獲取所有結果,而不會阻塞,并在主線程的 for-select 循環中讀取它們:


func work(msg string, d time.Duration, ret chan<- string) {

    time.Sleep(d) // Work emulation.

    select {

    case ret <- msg:

    default:

    }

}


// ...


const N = 2

ch := make(chan string, N)


go work("printed", 100*time.Millisecond, ch)

go work("not printed", 1000*time.Millisecond, ch)


timeout := time.After(500 * time.Millisecond)

loop:

for received := 0; received < N; received++ {

    select {

    case msg := <-ch:

        fmt.Println(msg)

    case <-timeout:

        fmt.Println("timeout!")

        break loop

    }

}

游樂場:http : //play.golang.org/p/PxeEEJo2dz。


查看完整回答
反對 回復 2021-11-29
?
慕標5832272

TA貢獻1966條經驗 獲得超4個贊

另一種方法是在內部對其進行監控,您的問題是有限的,但我假設您正在通過循環啟動 goroutines,即使您不是,您也可以重構它來為您工作,但您可以這樣做這兩個示例之一,第一個將超時每個請求單獨超時,第二個將超時整批請求,如果時間過長則繼續


var wg sync.WaitGroup

wg.Add(1)

go func() {

    success := make(chan struct{}, 1)

    go func() {

        // send your request and wait for a response

        // pretend response was received

        time.Sleep(5 * time.Second)

        success <- struct{}{}

        // goroutine will close gracefully after return     

        fmt.Println("Returned Gracefully")

    }()


    select {

    case <-success:

        break

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

        break

    }


    wg.Done()

    // everything should be garbage collected and no longer take up space

}()


wg.Wait()


// do whatever with what you got    

fmt.Println("Done")

time.Sleep(10 * time.Second)

fmt.Println("Checking to make sure nothing throws errors after limbo goroutine is done")

或者,如果您只是想要一個通用的簡單方法來超時所有請求,您可以執行以下操作


var wg sync.WaitGroup

waiter := make(chan int)

wg.Add(1)

go func() {

    success := make(chan struct{}, 1)

    go func() {

        // send your request and wait for a response

        // pretend response was received

        time.Sleep(5 * time.Second)

        success <- struct{}{}

        // goroutine will close gracefully after return     

        fmt.Println("Returned Gracefully")

    }()


    select {

    case <-success:

        break

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

        // control the timeouts for each request individually to make sure that wg.Done gets called and will let the goroutine holding the .Wait close

        break

    }

    wg.Done()

    // everything should be garbage collected and no longer take up space

}()


completed := false

go func(completed *bool) {

    // Unblock with either wait

    wg.Wait()

    if !*completed {

        waiter <- 1         

        *completed = true

    }       

    fmt.Println("Returned Two")

}(&completed)


go func(completed *bool) {

    // wait however long

    time.Sleep(time.Second * 5)

    if !*completed {

        waiter <- 1         

        *completed = true

    }       

    fmt.Println("Returned One")

}(&completed)



 // block until it either times out or .Wait stops blocking 

 <-waiter


// do whatever with what you got    

fmt.Println("Done")

time.Sleep(10 * time.Second)

fmt.Println("Checking to make sure nothing throws errors after limbo goroutine is done")

這樣你的 WaitGroup 將保持同步,你不會有任何 goroutines 處于不確定狀態


http://play.golang.org/p/g0J_qJ1BUT在這里試試你可以改變周圍的變量以查看它的工作方式不同


編輯:我在移動設備上如果有人可以修復格式,那將是非常感謝。


查看完整回答
反對 回復 2021-11-29
  • 3 回答
  • 0 關注
  • 405 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號