是否有任何API让main
goroutine永远睡觉?
换句话说,我希望我的项目总是运行,除非我停止它。
答案 0 :(得分:27)
你可以使用许多永远阻止的结构,而不是" eat"你的CPU。
例如select
没有任何case
(并且没有default
):
select{}
或从没有人发送任何内容的频道收到:
<-make(chan int)
或者从nil
频道接收也会永久阻止:
<-(chan int)(nil)
或者通过nil
频道发送也会永久阻止:
(chan int)(nil) <- 0
或锁定已锁定的sync.Mutex
:
mux := sync.Mutex{}
mux.Lock()
mux.Lock()
如果您确实想提供退出方式,可以使用简单的渠道。提供quit
频道,并从中接收。当您想要退出时,请关闭quit
频道作为&#34;关闭频道上的接收操作始终可以立即进行,在之前发送的任何值之后产生元素类型zero value已收到&#34;。
var quit = make(chan struct{})
func main() {
// Startup code...
// Then blocking (waiting for quit signal):
<-quit
}
// And in another goroutine if you want to quit:
close(quit)
请注意,发出close(quit)
可能会随时终止您的应用。引自Spec: Program execution:
程序执行从初始化主包然后调用函数
main
开始。当该函数调用返回时,程序退出。 它不会等待其他(非main
)goroutines完成。
执行close(quit)
时,main()
函数的最后一个语句可以继续,这意味着main
goroutine可以返回,所以程序退出。
答案 1 :(得分:7)
这取决于用例来选择你想要的睡眠类型。
@icza提供了一个简单易用的解决方案,但如果您希望系统能够优雅地关闭,我想给你一些甜食。
你可以这样做:
func mainloop() {
exitSignal := make(chan os.Signal)
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM)
<-exitSignal
systemTeardown()
}
在你的主要:
func main() {
systemStart()
mainloop()
}
通过这种方式,你不仅可以要求你的主人永远睡觉,而且你的代码收到来自操作系统的INT
或TERM
信号之后你可以做一些优雅的关机工作,比如{{1} }或ctrl+C
。
答案 2 :(得分:0)
另一种阻止goroutine的解决方案。此解决方案可防止Go-Runtime抱怨死锁:
import "time"
func main() {
for {
time.Sleep(1138800 * time.Hour)
}
}