Go进程在捕获SIGINT和SIGTERM时过早死亡

Go进程在捕获SIGINT和SIGTERM时过早死亡,go,signals,Go,Signals,我有一个相当直接的信号处理和清理过程: func signalHandler(shutdown func() error) { // Make signal channel and register notifiers for Interupt and Terminate sigchan := make(chan os.Signal, 1) signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM) // Bl

我有一个相当直接的信号处理和清理过程:

func signalHandler(shutdown func() error) {
    // Make signal channel and register notifiers for Interupt and Terminate
    sigchan := make(chan os.Signal, 1)
    signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM)

    // Block until we receive a signal on the channel
    <-sigchan

    // Shutdown now that we've received the signal
    if err := shutdown(); err != nil {
        msg := fmt.Sprintf("shutdown error: %s", err.Error())
        log.Fatal(msg)
    }

    log.Println("shutdown procedure complete") 

    // Make a clean exit
    os.Exit(0)
}
func信号处理程序(shutdown func()错误){
//建立信号通道并注册中断和终止通知程序
sigchan:=make(通道操作信号,1)
signal.Notify(sigchan、syscall.SIGINT、syscall.SIGTERM)
//阻塞,直到我们收到频道上的信号

问题是对
Run()
的调用是
main()
中最后一个真正的操作。只要
Run()
返回,
main()
返回,当
main()
返回时,程序退出。我通常将信号处理放在
main()
本身,而不是任何goroutine中,以确保
main()
在我处理完信号关闭后程序之前不会返回


(从评论中可以看出,现在已经排序,重新发布作为答案。)

问题是对
Run()
的调用是
main()
中的最后一个实际操作。只要
Run()
返回,
main()
返回,并且当
main()
返回时,程序退出。我通常将信号处理放在
main()中
本身,而不是在任何goroutine中,以确保
main()
在处理完信号关闭后程序之前不会返回


(从评论中,现在已排序,重新发布作为答案。)

s.done
缓冲通道吗?
shutdown
不调用
*Server.shutdown()
,它是
*Server.shutdown()
-我将它直接传递到
*Server.Run()中的信号处理器中
方法。我尝试了缓冲和非缓冲-效果相同。没有同步来等待运行完成,因此不能保证永远打印,但“此处全部完成”应该写入日志。日志输出是标准的非缓冲标准吗?是
main()
调用
server.Run()
并检查是否有错误,然后记录它——这是它最后做的事情。
s.done
是缓冲通道吗?
shutdown
不调用
*Server.shutdown()
,它是
*Server.shutdown()
-我将它直接传递到
*服务器中的信号处理器中。Run()
方法。我尝试了缓冲和非缓冲-效果相同。没有同步来等待运行完成,因此不能保证永远打印,但“此处全部完成”应该写入日志。日志输出是标准的非缓冲标准吗?是
main()
调用
server.Run()
并检查是否有错误,然后将其记录下来——这是它最后做的事情。
func (s *Server) Run() error {
    go signalHandler(s.Shutdown) 
    ...

    <-s.done // block until done 
    log.Println("done running!") 
    return nil 
}

func (s *Server) Shutdown() error {
    s.done <- true 
    log.Println("all done here!") 
    return nil 
}