您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

我如何杀死goroutine

我如何杀死goroutine

您可以使用select和频道杀死无限循环!

var quit chan struct{}

func startLoop() {
    quit := make(chan struct{})
    go loop()
}

func stopLoop() {
    // As mentioned by Kaedys
    //close(quit)
    // permits signalling everyone havins such a `case <-quit:`
    // statement to be stopped at once, which might be even better.
    quit <- struct{}{}
}

// BTW, you cannot call your function main, it is reserved
func loop() {
    for {
        select {
        case <-quit:
            return # better than break
        default:
            // do stuff. I'd call a function, for clarity:
            do_stuff()
        }
    }
}

很不错的Go交换,不是吗?

现在,这有什么奇怪的地方chan struct{}?这是一个零尺寸的频道。我们只能用空结构填充它(即:)struct{}{}。可能是a chan bool或其他,因为我们不使用频道的内容。重要的是,我们使用quit通道通知goroutine中的无限循环,该该停止了。

select语句用于捕获来自渠道的内容。这是一条阻塞语句(case除非您放置一条default语句,否则它将停止执行,直到在所调查的通道之一中放入某些内容为止)。在这种情况下,每次select执行时,如果将某些内容放入quitdo_stuff()将被调用,则循环将中断。如果您去过Go Tour,那么您已经知道这一点。

其他很酷的并发模式可以在Go Blog中找到。

最后,为了获得更多的乐趣,您可以do_stuff使用Tickers 来要求您的函数在固定的时间间隔执行,而不是像这样消耗100%的cpu

import "time"

// [...]

func loop() {
    // This ticker will put something in its channel every 2s 
    ticker := time.NewTicker(2 * time.Second)
    // If you don't stop it, the ticker will cause memory leaks
    defer ticker.Stop()
    for {
        select {
        case <-quit:
            return
        case <-ticker.C:
            // do stuff. I'd call a function, for clarity:
            do_stuff()
        }
    }
}

select由于我们删除了该default语句,因此此处处于阻塞状态。

Go 2022/1/1 18:13:57 有673人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶