Linux 在golang中处理SIGINT(ctrl-c)以将其转换为紧急状态
我的目标是在CLI上有一个SIGINT处理程序,即Ctrl-C,它将允许运行延迟的函数调用,而不是导致硬退出。这种情况的用例是在一个测试套件中,测试运行时间很长,我希望CLI用户能够尽早使用Ctrl-C触发测试清理。测试清理函数都应该在每个测试函数的延迟函数堆栈上,因此在我看来,将SIGINT降级为panic应该会导致这些清理函数运行 下面的代码是我的尝试。如果你用go run运行这个,你会看到Linux 在golang中处理SIGINT(ctrl-c)以将其转换为紧急状态,linux,go,goroutine,deferred,sigint,Linux,Go,Goroutine,Deferred,Sigint,我的目标是在CLI上有一个SIGINT处理程序,即Ctrl-C,它将允许运行延迟的函数调用,而不是导致硬退出。这种情况的用例是在一个测试套件中,测试运行时间很长,我希望CLI用户能够尽早使用Ctrl-C触发测试清理。测试清理函数都应该在每个测试函数的延迟函数堆栈上,因此在我看来,将SIGINT降级为panic应该会导致这些清理函数运行 下面的代码是我的尝试。如果你用go run运行这个,你会看到 $ go run . regular action ran! post-Sleep action r
$ go run .
regular action ran!
post-Sleep action ran!
deferred action ran!
但是如果你在5秒钟的睡眠中打断它,你会看到这样的画面:
regular action ran!^Cpanic: interrupt
goroutine 8 [running]:
main.panic_on_interrupt(0xc00007c180)
/home/curran/dev/test/main.go:12 +0x5e
created by main.main
/home/curran/dev/test/main.go:20 +0xab
exit status 2
我添加了中断处理程序和goroutine,因为我认为这会将SIGINT降级为一个恐慌状态,并允许调用fmt.Printfdeferred操作!执行。然而,事实并非如此
下面是有问题的代码:
包干管
进口
fmt
时间
操作系统
操作系统/信号
功能紧急接通中断切换信号{
信号:=
睡眠阻止在指定的时间内运行goroutine。
您可以推迟清理代码。
此外,您可以在单独的goroutine中运行耗时的测试,而不是在那里惊慌失措。
尽可能避免使用死机。延时是在每次执行例行程序的基础上执行的。如果goroutine a中的死机未恢复,则会导致程序终止,而不会在其他goroutine B、C……中执行延时。延时是在保留封闭函数时执行的。其他goroutine中的死机不会导致其他函数终止左/右,程序刚刚终止。啊,我明白了。知道这一点很有帮助!我想我需要做的是维护一个延迟清理操作的全局堆栈,并在收到SIGINT时手动从该堆栈中弹出操作。你直接告诉另一个goroutine恐慌。你能做的最接近的事情是让每个goroutine定期检查一个p介绍了anic状态和if shouldPanic{panic}Go 1.16,如果您已经在使用上下文,或者添加上下文很容易,那么这可能会很有用。
func main() {
fmt.Printf("regular action ran!")
defer fmt.Printf("deferred action ran!")
go startLongRunningTest()
defer longRunningTestCleanupCode()
//time.Sleep(5 * time.Second)
//fmt.Printf("post-Sleep action ran!")
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<-c
}