Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在golang中处理SIGINT(ctrl-c)以将其转换为紧急状态_Linux_Go_Goroutine_Deferred_Sigint - Fatal编程技术网

Linux 在golang中处理SIGINT(ctrl-c)以将其转换为紧急状态

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

我的目标是在CLI上有一个SIGINT处理程序,即Ctrl-C,它将允许运行延迟的函数调用,而不是导致硬退出。这种情况的用例是在一个测试套件中,测试运行时间很长,我希望CLI用户能够尽早使用Ctrl-C触发测试清理。测试清理函数都应该在每个测试函数的延迟函数堆栈上,因此在我看来,将SIGINT降级为panic应该会导致这些清理函数运行

下面的代码是我的尝试。如果你用go run运行这个,你会看到

$ 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
}