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

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

從 goroutine 之外停止 goroutine

從 goroutine 之外停止 goroutine

Go
慕少森 2022-06-27 15:30:44
我在這里有一個 go 例程,當上下文過期時,它需要從外部 go 例程中停止。但是,當上下文過期時,go 例程不會停止,并且會繼續運行,即使控制它的 go 例程停止也是如此。package mainimport (    "context"    "fmt"    "time")func main() {    ctxParent := context.Background()    ch := make(chan bool)    d := 5 * time.Second    ctx, cancel := context.WithTimeout(ctxParent, d)    defer cancel()    go doSomething(ctx, ch)    // go func() {    select {    // done    case _ = <-ch:        fmt.Println("goroutine finished")    }    fmt.Println("waiting 11 seconds on main thread, ending all go routines")    time.Sleep(11 * time.Second)    fmt.Println(">>>> END")}func doSomething(ctx context.Context, ch chan<- bool) {    // how to kill this go routine if context expires??    go func(ctx context.Context) {        fmt.Println("LOTS OF WORK TIME..")        for i := 0; i < 1000; i++ {            time.Sleep(1 * time.Second) // LOTS OF WORK            fmt.Println(i)        }    }(ctx)    select {    case _ = <-ctx.Done():        fmt.Println("*** Go routine timed out in 5 seconds!!! ****")        ch <- true        return    }}這將打?。╤ttps://play.golang.org/p/L8u51odiHxS)LOTS OF WORK TIME..01234*** Go routine timed out in 5 seconds!!! ****goroutine finishedwaiting 11 seconds on main thread, ending all go routines56789101112131415>>>> END它不應該打印 5,6,7,8... 等等。有沒有辦法殺死這個內部 go 例程?
查看完整描述

2 回答

?
慕妹3242003

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

您必須在 goroutine 中檢查上下文過期/取消:


 go func(ctx context.Context) {

        fmt.Println("LOTS OF WORK TIME..")

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

            select {

              case <-ctx.Done():

                  return

              default:

            }

            time.Sleep(1 * time.Second) // LOTS OF WORK

            fmt.Println(i)

        }


    }(ctx)


查看完整回答
反對 回復 2022-06-27
?
DIEA

TA貢獻1820條經驗 獲得超3個贊

就像 Burak Serdar 所說,你必須檢查 goroutine 中上下文的狀態,但不僅僅是在 goroutine 開始時:你必須在 goroutine 中定期檢查。


go func(ctx context.Context) {

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

    select {

    case <-ctx.Done():

      return

    default:

      // do some work

    }

  }

}(ctx)

一般來說,不應該從外部殺死一個 goroutine;它必須自己檢查并意識到時間到了。


查看完整回答
反對 回復 2022-06-27
  • 2 回答
  • 0 關注
  • 127 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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