【问题标题】:OK to exit program with active goroutine?可以退出带有活动 goroutine 的程序吗?
【发布时间】:2014-10-20 12:41:56
【问题描述】:

取如下代码sn-p:

func main() {
    ch := make(chan int)
    quit := make(chan int)
    go func() {
        for {
            ch <- querySomePeriodicThing()
        }
    }()

    // ...

loop:
    for {
        select {
        case <-ch: handlePeriodicThing()
        case <-quit: break loop
        }
    }
}

goroutine 应该在执行期间运行。当 select 语句从 quit 通道接收到某些内容时,它会跳出循环并结束程序,而不会尝试停止 goroutine。

我的问题:这是否会产生任何间歇性的不利影响,运行一次或两次并不明显?我知道在其他语言中应该在程序结束之前清理(即退出)线程,但是 go 不同吗?假设 querySomePeriodicThing() 没有打开文件描述符或套接字或任何不打开的东西。

【问题讨论】:

    标签: go goroutine


    【解决方案1】:

    Goroutines 不是线程,它们非常轻量级,运行时会在它们不再运行或程序退出时自动清理它们。

    【讨论】:

    • “...运行时自动清理它们...”的来源?
    • @fr4nk 主要体验运行时'
    • “清理”的定义是什么?
    【解决方案2】:

    As mentioned in the spec,当main函数完成时你的程序将退出:

    程序执行从初始化主包开始,然后调用函数main。当该函数调用返回时,程序退出。它不会等待其他(非main)goroutine 完成。

    因此,从语言的角度来看,您还有其他 goroutine 仍在运行这一事实不是问题。这可能仍然是一个问题,具体取决于您的程序正在做什么。

    如果 goroutine 创建了一些应该在程序退出之前清理的资源,那么中途停止执行可能是一个问题:在这种情况下,你应该让你的 main 函数先等待它们完成.没有与pthread_join 等效的代码,因此您需要自己编写代码(例如,使用频道或sync.WaitGroup)。

    请注意,某些资源会在进程退出时由操作系统自动清理(例如打开的文件、文件锁定等),因此在某些情况下不需要特殊清理

    【讨论】:

    • 额外的问题:它是在 main 退出后在 go 例程中运行 defer 语句,还是那些被切断的语句也已经死了?
    • @ams 我没有这方面的规范参考,但defer 声明appear to get cut off dead, too
    猜你喜欢
    • 2020-12-25
    • 2011-09-25
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 1970-01-01
    • 2023-03-25
    • 2019-06-25
    相关资源
    最近更新 更多