簡體   English   中英

如何使用頻道通知goroutine正確退出

[英]How to use channel to notify a goroutine to quit properly

注意:我使用google搜索了此主題,並閱讀了幾乎所有可以找到的內容,但仍然無法獲得正確/合理/生產就緒的答案。

基本上所有答案都是相似的,就像這樣: 如何停止一個常規程序 ,所有模式都相同,也不例外:實際的工作是fmt.Println(1)來打印某些內容,或者只是// Do other stuff

但是,如果將實際工作保留在for select default case branch ,那么它將被執行多次,以打印某些內容就可以了,但顯然還沒有准備好進行實際工作。

我能想象的唯一有效的方法是將實際工作放到一個案例分支上,然后向該案例發送一個信號以通知它開始,例如: 操場 ,但只是感到不安,也使用這種方法,是否會造成一些問題可能嗎?

添加了代碼片段以准確顯示我要實現的目標: https : //play.golang.org/p/7xjjiW7XdoQ ,我想在客戶端關閉連接時實現,然后立即終止我的處理程序,釋放資源,然后無條件退出。

您不想在多個地方檢查取消信號,而不是使用for select循環。 但是為了不阻塞,您仍然必須使用select (默認情況下為空),這會使它有點笨拙。 我使用的是context.Context而不是“普通取消頻道”,但是想法是一樣的:

func doWork(ctx context.Context) {
    fmt.Println("Doing some work 1")
    time.Sleep(time.Second * 5)
    // check is the task cancelled
    select {
    case <-ctx.Done():
        fmt.Println("cancelled at checkpoint 1")
        return
    default:
    }
    fmt.Println("Doing some work 2")
    time.Sleep(time.Second * 5)
    // check is the task cancelled
    select {
    case <-ctx.Done():
        fmt.Println("cancelled at checkpoint 2")
        return
    default:
    }
    fmt.Println("Doing some work 3")
    time.Sleep(time.Second * 5)
}

func main() {
    var wg sync.WaitGroup
    wg.Add(1)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
    defer cancel()
    go func() {
        doWork(ctx)
        wg.Done()
    }()
    wg.Wait()
    fmt.Println("done")
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM