【问题标题】:Do goroutines keep running even if main function is terminated?即使 main 函数终止,goroutines 是否会继续运行?
【发布时间】:2021-03-03 13:28:54
【问题描述】:
我正在运行一个服务器,其中 main 触发了几个 go 例程。像这样:
main() {
go someFn(){
// will run for infinite time()
}
go otherFn()
}
我有两个疑问:
-
如果主函数退出了怎么办?这些线程会继续运行还是会以 main 函数终止?
-
如果不是,那么让主函数永远运行/或运行直到我需要它的最佳方法是什么?目前,我正在使用select{} 命令让它永远运行!有没有比select{}更好更有效的方法
【问题讨论】:
标签:
multithreading
go
goroutine
【解决方案1】:
我建议完整阅读 the language specification — Go 是极少数语言规范之一,其语言规范可以在两次午餐(或一次午餐)中真正阅读 - 如果这是你的,我不知道,第三第四种编程语言)。
引用it:
程序执行首先初始化main 包,然后调用函数main。当该函数调用返回时,程序退出。它不会等待其他(非主)goroutine 完成。
我要补充一点,逻辑上让 main 等待所有非主 goroutine 将是一件坏事,原因有两个:
-
这很容易造成您可以等待程序关闭一段不确定的时间即使您不希望这样(而且您并不总是希望这样)。
从逻辑上讲,这需要发明一种“特殊”方式来结束main——类似于abort(3) from C,而拥有这样的方式肯定会被滥用。
-
任何你实际需要等待它们的 goroutine 的合理使用都需要显式同步 - 仅根据语言规范及其 memory model。
也就是说,当你想等待未完成的 goroutine 时,你必须明确地这样做。
【解决方案2】:
当函数main()返回时程序退出。
如果someFn 或otherFn 之一永远运行,则直接在main 的末尾调用该函数。 main 函数永远不会随着这个变化而退出。
如果两个函数都不会永远运行,则使用 sync.WaitGroup 等待 goroutines 然后退出。
空的 select 语句 select {} 有效地永远阻塞了一个 goroutine。
【解决方案3】:
[Do] 即使 main 函数终止,go 例程也会继续运行?
没有。
每周询问一次。