2016-09-15 144 views
2

我可以运行一些中断的清理(当我按ctrlc)。陷阱os.Exit在golang

$ go build 
$ ./exit 
^Creceived interrupt signal 

是否有可能捕获同样的方式os.Exit通话和运行程序退出之前的一些代码?代码:

package main 

import (
    "fmt" 
    "os" 
    "os/signal" 
    "syscall" 
    "time" 
) 

func main() { 
    handleInterrupt(2) 
    time.Sleep(2 * time.Second) 
    os.Exit(1) // how to trap it? 
} 
func handleInterrupt(intrptChSize int) { 
    s := make(chan os.Signal, intrptChSize) 
    signal.Notify(s, 
     syscall.SIGABRT, 
     syscall.SIGALRM, 
     syscall.SIGBUS, 
     syscall.SIGCHLD, 
     syscall.SIGCONT, 
     syscall.SIGEMT, 
     syscall.SIGFPE, 
     syscall.SIGHUP, 
     syscall.SIGILL, 
     syscall.SIGINFO, 
     syscall.SIGINT, 
     syscall.SIGIO, 
     syscall.SIGIOT, 
     syscall.SIGKILL, 
     syscall.SIGPIPE, 
     syscall.SIGPROF, 
     syscall.SIGQUIT, 
     syscall.SIGSEGV, 
     syscall.SIGSTOP, 
     syscall.SIGSYS, 
     syscall.SIGTERM, 
     syscall.SIGTRAP, 
     syscall.SIGTSTP, 
     syscall.SIGTTIN, 
     syscall.SIGTTOU, 
     syscall.SIGURG, 
     syscall.SIGUSR1, 
     syscall.SIGUSR2, 
     syscall.SIGVTALRM, 
     syscall.SIGWINCH, 
     syscall.SIGXCPU, 
     syscall.SIGXFSZ) 
    go func() { 
     for sig := range s { 
      fmt.Printf("received %s signal\n", sig) 
      //cleanup() 
     } 
    }() 
} 

我知道我可以在这个例子中,每个os.Exit()代码之前,只需要运行cleanup手动:

cleanup() 
os.Exit(1) 

但在我真正的项目,我输入代码,我不能编辑。此代码包含os.Exit调用,我希望在程序退出前进行一些清理操作,而无需编辑导入的代码。

+1

你应该只处理有意义的信号。您可能不希望从“SIGWINCH”之类的非终止信号或每个“SIGALRM/SIGCTALRM”,“SIGXCPU”等中“清除”。您还有那些根本无法处理的信号。 – JimB

+0

而不是'os.Exit(x)'的核选项尝试以下变体:https://play.golang.org/p/kHIfKoXuKt –

+0

@MartinGallagher我无法从导入的代码中删除os.Exit(x) –

回答

4

你不能。来自TFM:

该程序立即终止;延迟功能不运行。