2016-09-15 142 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:

該程序立即終止;延遲功能不運行。