首页 > 后端开发 > Golang > 正文

如何优雅地停止 Go 例程:避免死锁和无响应进程的指南?

Linda Hamilton
发布: 2024-10-28 14:11:02
原创
535 人浏览过

 How to Gracefully Stop a Go Routine: A Guide to Avoiding Deadlocks and Unresponsive Processes?

如何优雅地停止 Go 例程

在 Go 中,goroutines 提供轻量级并发,但优雅地终止它们可能具有挑战性。这个问题解决了向 Goroutine 发送信号以停止其执行的需要。

提供的代码演示了通过将布尔标志 (tooLate) 设置为 true 来尝试停止 Goroutine。然而,这种方法是有问题的,因为从通道读取数据会阻塞 goroutine。

解决方案 1:使用附加通道

该解决方案涉及使用第二个通道(太晚了)传达停止信号。即使 goroutine 没有主动读取该通道,该通道仍保持打开状态。

<code class="go">func main() {
    tooLate := make(chan struct{}) // Unbuffered channel for stop signal
    proCh := make(chan string)

    go func() {
        for {
            fmt.Println("working")
            time.Sleep(1 * time.Second)
            select {
            case <-tooLate:
                fmt.Println("stopped")
                return
            case proCh <- "processed": // Non-blocking send
            default: // Allows the goroutine to continue without blocking
            }
            fmt.Println("done here")
        }
    }()

    select {
    case proc := <-proCh:
        fmt.Println(proc)
    case <-time.After(1 * time.Second):
        fmt.Println("too late")
        close(tooLate) // Signal to goroutine to stop
    }

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}</code>
登录后复制

在此解决方案中,当时间限制到期时,tooLate 通道将关闭,这会导致 goroutine 退出其阻塞 select 语句并返回。

解决方案 2:使用sync.Cond

或者,您可以使用sync.Cond 类型来实现更复杂的信号机制。下面是一个示例:

<code class="go">func main() {
    var stopped bool
    cond := sync.NewCond(new(sync.Mutex))

    go func() {
        for {
            cond.L.Lock()
            defer cond.L.Unlock()

            if stopped {
                fmt.Println("stopped")
                return
            }
            fmt.Println("working")
            cond.Wait() // Wait for the signal to stop
        }
    }()

    time.Sleep(1 * time.Second)
    cond.Signal() // Send the stop signal

    time.Sleep(4 * time.Second)
    fmt.Println("finish\n")
}</code>
登录后复制

通过这种方法,goroutine 会等待 cond.Wait() 方法,直到收到来自 cond.Signal() 的信号。

以上是如何优雅地停止 Go 例程:避免死锁和无响应进程的指南?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!