如何安全地关闭延迟块中的通道?

考虑以下示例

package main


import (

    "fmt"

    "time"

)


func main() {

    ticker := time.NewTicker(2 * time.Second)

    done := make(chan bool)

    defer func() {

        fmt.Println("exiting..")

        done <- true

        close(done)

    }()

    go func(ticker *time.Ticker, done chan bool) {

        for {

            select {

            case <-done:

                fmt.Println("DONE!")

                break

            case <-ticker.C:

                fmt.Println("TICK!...")

            }

        }

    }(ticker, done)

    time.Sleep(7 * time.Second)

}

等待接收的 goroutine 从未done接收到(我猜)主 goroutine 预先完成。但是,如果我将主 goroutine 的睡眠时间更改为 8 秒,它会收到一条消息;为什么对睡眠时间有这种依赖性?


是不是因为有第二个区别让 goroutine 保持活力并且没有足够的时间杀死它?


我该如何优雅地杀死 goroutine?


慕的地6264312
浏览 97回答 1
1回答

MMMHUHU

您需要确保 main 在 goroutine 完成之前不会返回。最简单的方法是使用 WaitGroup:var wg sync.WaitGroupdefer wg.Wait()wg.Add(1)go func() {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; // …注意defers是逆序运行的,所以一定要放在defer wg.Wait()之前defer close(done),否则会死锁。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go