我有一个http服务器(使用http.Handle
启动),我想做一些操作。
我该怎么做(在Linux上)?是否可以在ctrl-C的情况下进行这些操作?
我不熟悉unix信号所以答案可能很简单。
答案 0 :(得分:16)
使用kostix答案,我构建了这段代码(现在适用于Go1)来捕获中断信号并在退出之前执行一些操作:
go func() {
sigchan := make(chan os.Signal, 10)
signal.Notify(sigchan, os.Interrupt)
<-sigchan
log.Println("Program killed !")
// do last actions and wait for all write operations to end
os.Exit(0)
}()
// start main program tasks
答案 1 :(得分:3)
您可以使用signal包订阅TERM和INT信号。但请注意,这些信号仅在明确杀死进程时发送;正常退出(由流程本身启动)不涉及任何类型的信号。我认为正常退出只是在主程序中做一些事情(据说应该产生工人goroutines然后等待它们。)
阅读man 7 signal
以获取有关POSIX信号的更多常规信息。
答案 2 :(得分:0)
我认为作者不仅对 Ctrl + C 感兴趣,而且为Linux提供更广泛的解决方案(对于Windows信号,请参阅x/sys/windows):
package main
import (
"os"
"os/signal"
"syscall"
"fmt"
)
func getFireSignalsChannel() chan os.Signal {
c := make(chan os.Signal, 1)
signal.Notify(c,
// https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
syscall.SIGTERM, // "the normal way to politely ask a program to terminate"
syscall.SIGINT, // Ctrl+C
syscall.SIGQUIT, // Ctrl-\
syscall.SIGKILL, // "always fatal", "SIGKILL and SIGSTOP may not be caught by a program"
syscall.SIGHUP, // "terminal is disconnected"
)
return c
}
func exit() {
syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
}
func main() {
exitChan := getFireSignalsChannel()
input, err := os.Open("input.txt")
if err != nil {
panic(err)
}
defer input.Close()
<-exitChan
fmt.Println("Exiting!")
return
// All main deferreds executed here even in case of panic.
// Non-main deferreds are not executed here.
}
P.S。没有信号处理os.Exit
。
在 Ctrl + C 上进行此配置,或者在接收其他信号程序时,将os.Signal
推入频道exitChan
,这将取消阻止<-exitChan
操作和{{ 1}}函数将在最后一行继续执行,然后返回,然后执行延迟函数。
对于非主延期,您可以: