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

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

在 Golang 中使用上下文超時停止運行函數

在 Golang 中使用上下文超時停止運行函數

Go
Helenr 2022-05-23 17:36:46
我想利用 golang 中的上下文在超時時用于取消。編碼:package mainimport "fmt"import "time"import "context"func F(ctx context.Context) error {  ctx, cancel := context.WithTimeout(ctx,3*time.Second)  defer cancel()  for i:=0;i<10;i++ {    time.Sleep(1 * time.Second)    fmt.Println("No: ",i)  }  select {    case <-ctx.Done():      fmt.Println("TIME OUT")      cancel()      return ctx.Err()    default:      fmt.Println("ALL DONE")      return nil  }}func main() {  ctx := context.Background()  err := F(ctx)  if err != nil {    fmt.Println(err)  }else {    fmt.Println("Success")  }}期望:上面的代碼應該在 counter 停止運行循環2,因為超時是 3 秒,循環運行 1 秒。所以我期待這樣的事情:No:  0No:  1No:  2TIME OUTcontext deadline exceeded實際:實際發生的情況是循環繼續運行直到完成,即使上下文遇到超時并且選擇偵聽器在<-ctx.Done(). 此代碼打?。篘o:  0No:  1No:  2No:  3No:  4No:  5No:  6No:  7No:  8No:  9TIME OUTcontext deadline exceeded超時滿足后如何停止函數執行?
查看完整描述

1 回答

?
紅糖糍粑

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

context.Context只能中繼發生超時或取消的消息。它無權實際停止任何 goroutines(有關詳細信息,請參閱取消 Go 中的阻塞操作)。goroutine 本身負責檢查超時和取消,并提前中止。


你有一個循環,它無條件地迭代 10 次并打印一些東西。而且您只在循環后檢查超時。


您必須將上下文檢查移動到循環中:


func F(ctx context.Context) error {

    ctx, cancel := context.WithTimeout(ctx, 3*time.Second)

    defer cancel()

    for i := 0; i < 10; i++ {

        select {

        case <-ctx.Done():

            fmt.Println("TIME OUT")

            return ctx.Err()

        default:

            time.Sleep(1 * time.Second)

            fmt.Println("No: ", i)

        }

    }

    fmt.Println("ALL DONE")

    return nil

}

通過此更改,輸出將是(在Go Playground上嘗試):


No:  0

No:  1

No:  2

No:  3

TIME OUT

context deadline exceeded

注意:無論您看到"No: 3"打印可能會或可能不會發生,因為任何迭代都需要 1 秒,并且超時是 3 秒 = 3 * 迭代延遲,所以是先發生超時還是第 4 次迭代首先開始是“活潑的”。如果將超時時間減少到 2900 毫秒,"No: 3"則不會打印。


查看完整回答
反對 回復 2022-05-23
  • 1 回答
  • 0 關注
  • 573 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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