永远去项目的主要睡眠?

时间:2016-04-05 06:48:58

标签: go blocking goroutine

是否有任何API让main goroutine永远睡觉?

换句话说,我希望我的项目总是运行,除非我停止它。

3 个答案:

答案 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()
}

通过这种方式,你不仅可以要求你的主人永远睡觉,而且你的代码收到来自操作系统的INTTERM信号之后你可以做一些优雅的关机工作,比如{{1} }或ctrl+C

答案 2 :(得分:0)

另一种阻止goroutine的解决方案。此解决方案可防止Go-Runtime抱怨死锁:

import "time"

func main() {
    for {
        time.Sleep(1138800 * time.Hour)
    }
}