如何从goroutine中结束一个Go程序

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

How to end a go program from a goroutine

问题

我正在尝试在使用Go编写的命令行界面中实现一些非典型的行为。

我有一个长时间运行的函数,并且我希望在某人通过ctrl-c退出该函数时运行一个清理函数。

以下是代码的示例:

func longRunningFunction() {
    //一些设置
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        <-sigs
        fmt.Println("收到中断信号")
        cleanup()
    }()
    //长时间运行的命令
    fmt.Println("结束")
}

在正常情况下,不需要使用ctrl-c,函数将正常完成。(因此,我不能在主线程中有一个(如通道)阻塞,直到清理goroutine完成。)然而,在用户按下ctrl-c的情况下,我希望立即结束程序,而不打印"结束"(最好也不完成长时间运行的命令)。

但目前情况并非如此。当前的命令行输出如下所示:

...
//长时间运行命令的输出
^C收到中断信号
//清理代码的输出
$
//更多长时间运行命令的输出
结束

我对几个问题感到困惑 - 为什么程序在提示符返回后仍然打印输出,为什么仍然打印"结束"?我如何避免这种行为?在Go中是否可能出现这种情况?谢谢!

英文:

I'm trying to implement some non-typical behavior in a command line interface written in go.

I have a function that runs for a long time, and I want to have a cleanup function that runs when someone ctrl-c's out of that function.

Here's a mock-up of the code:

func longRunningFunction() {
    //some set up stuff
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

    go func() {
	    &lt;-sigs
        fmt.Println(&quot;Got an interrupt&quot;)
	    cleanup()
    }()
    //the long-running command
    fmt.Println(&quot;the end&quot;)
}

In the normal case, using ctrl-c will not be necessary and the function will finish normally. (Because of this, I can't have something (like a channel) in the main thread that blocks until the cleanup goroutine has finished.) However, in the case that a user does press ctrl-c, I would like to end the program immediately, not printing "the end" (and ideally not finishing the long-running command).

That's not happening right now. Currently, the command line output looks like this:

...
//long-running-command&#39;s output
^CGot an interrupt
//cleanup code&#39;s output
$
//more of long-running-command&#39;s output
the end

I'm confused on a few fronts - why is the program still printing after the prompt returns, and why is "the end" still being printed? How can I avoid this behavior? Is this scenario even possible in go? Thanks!

答案1

得分: 3

你正在信号处理程序之后继续执行。如果你想退出进程,请调用os.Exit函数:

go func() {
    <-sigs
    fmt.Println("收到中断信号")
    cleanup()
    os.Exit(2)
}()
英文:

You're continuing execution after your signal handler. If you want to exit the process, call os.Exit:

go func() {
    &lt;-sigs
    fmt.Println(&quot;Got an interrupt&quot;)
    cleanup()
    os.Exit(2)
}()

huangapple
  • 本文由 发表于 2017年3月16日 03:21:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/42818887.html
匿名

发表评论

匿名网友

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

确定