永远去项目的主要goroutine睡眠?

Dev*_*hou 18 go blocking goroutine

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

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

icz*_*cza 30

"睡眠"

你可以使用许多永远阻塞的结构,而不会"吃掉"你的CPU.

例如a select没有任何case(和没有default):

select{}
Run Code Online (Sandbox Code Playgroud)

或者从没有人发送任何内容的频道接收:

<-make(chan int)
Run Code Online (Sandbox Code Playgroud)

或者从nil频道接收也会永久阻止:

<-(chan int)(nil)
Run Code Online (Sandbox Code Playgroud)

或者在nil频道上发送也会永久阻止:

(chan int)(nil) <- 0
Run Code Online (Sandbox Code Playgroud)

或锁定已锁定的sync.Mutex:

mux := sync.Mutex{}
mux.Lock()
mux.Lock()
Run Code Online (Sandbox Code Playgroud)

退出

如果你想提供一种退出方式,一个简单的渠道就可以做到.提供quit频道,并从中接收.当您想要退出时,关闭quit通道,因为"关闭通道上的接收操作总是可以立即进行,在收到任何先前发送的值后产生元素类型的零值 ".

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)
Run Code Online (Sandbox Code Playgroud)

请注意,发布close(quit)可能会随时终止您的应用.引自规范:程序执行:

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

close(quit)被执行时,我们的最后一条语句main()的功能可以进行,这意味着main够程可以返回,所以程序退出.


nev*_*ets 7

这取决于用例来选择你想要的睡眠类型.

@icza提供了一个简单易用的解决方案,但是如果你想让你的系统优雅地关闭,我想给你一些甜食.

你可以这样做:

func mainloop() {
    exitSignal := make(chan os.Signal)
    signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM)
    <-exitSignal

    systemTeardown()
}
Run Code Online (Sandbox Code Playgroud)

在你的主要:

func main() {
    systemStart()
    mainloop()
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,你不仅可以让你的主人永远地睡觉,而且你可以在你的代码收到INTTERM发出来自操作系统的信号之后做一些优雅的关机工作,比如ctrl+Ckill.