为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕的地6264312 2023-03-15 15:24:33
考虑以下示例:package mainimport (    "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?
查看完整描述

1 回答

?
MMMHUHU

TA贡献1834条经验 获得超8个赞

您需要确保 main 在 goroutine 完成之前不会返回。

最简单的方法是使用 WaitGroup:


var wg sync.WaitGroup

defer wg.Wait()

wg.Add(1)

go func() {

    defer wg.Done()

    // …

注意defers是逆序运行的,所以一定要放在defer wg.Wait()之前defer close(done),否则会死锁。


查看完整回答
反对 回复 2023-03-15
  • 1 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信