trap os.Exit in golang

huangapple go评论72阅读模式
英文:

trap os.Exit in golang

问题

我可以在中断时(按下<kbd>ctrl</kbd><kbd>c</kbd>)运行一些清理操作。

$ go build 
$ ./exit
^C接收到中断信号

是否有可能以与os.Exit调用相同的方式捕获并在程序退出之前运行一些代码?代码如下:

package main

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

func main() {
	handleInterrupt(2)
	time.Sleep(2 * time.Second)
	os.Exit(1) // 如何捕获它?
}
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("接收到 %s 信号\n", sig)
            //cleanup()
		}
	}()
}

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

cleanup()
os.Exit(1)

但在我的实际项目中,我正在导入无法编辑的代码。这段代码包含os.Exit调用,我希望在程序退出之前进行一些清理操作,而不编辑导入的代码。

英文:

I can run some cleanup on interruption (when I press <kbd>ctrl</kbd><kbd>c</kbd>).

$ go build 
$ ./exit
^Creceived interrupt signal

Is it possible to trap the same way os.Exit call and run some code before program exits? The code:

package main

import (
	&quot;fmt&quot;
	&quot;os&quot;
	&quot;os/signal&quot;
	&quot;syscall&quot;
	&quot;time&quot;
)

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(&quot;received %s signal\n&quot;, sig)
            //cleanup()
		}
	}()
}

I know I can just run cleanup before each os.Exit() code manually in this example:

cleanup()
os.Exit(1)

But in my real project I am importing code which I cannot edit. This code contains os.Exit calls and I would like to do some cleanup before the program exits without editing imported code.

答案1

得分: 7

你不能。来自TFM的解释:

程序立即终止,延迟函数不会被执行。

英文:

You can't. from TFM:

> The program terminates immediately; deferred functions are not run.

huangapple
  • 本文由 发表于 2016年9月15日 19:02:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/39509447.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定