如果父进程终止,终止执行。

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

Kill exec if the parent process terminates

问题

我有一段类似于以下的 Go 代码:

func Foo() {
    cmd := exec.Command("需要很长时间的命令")
    err = cmd.Start()
    if err != nil {
        panic(err)
    }

    return
}

func main() {
    Foo()

    panic("程序突然退出")
}

即使主进程结束,sleep 命令仍然会继续运行,有可能将这两者关联起来,以便如果父进程结束,cmd 也会被终止吗?

英文:

I have a piece of go code like:

func Foo() {
    cmd := exec.Command("command that takes a long time")
    err = cmd.Start()
    if err != nil {
        panic(err)
    }


    return
}

func main() {
    Foo()

    panic("program quit abruptly")
}

The sleep command will still be active even though the main process ended, is it possible to link these so the cmd will be killed if the parent is?

答案1

得分: 0

如果你希望在程序退出时终止你启动的进程,你可以注入一个上下文:

func Foo(ctx context.Context) {
    cmd := exec.CommandContext(ctx, "需要很长时间的命令")
    _ = cmd.Start()

    return
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    Foo(ctx)
    defer cancel()

    panic("程序突然退出")
}

这段代码通过创建一个带有取消函数的上下文来实现。然后将该上下文发送到Foo函数,再传递给命令函数。当调用cancel函数时,上下文将被取消,从而终止子进程。为了确保上下文被取消,我们使用defer延迟调用cancel函数,这样可以确保在程序以任何原因退出时,包括发生 panic 时,上下文都会被取消。

如果你只希望在发生 panic 时取消上下文,可以稍微修改main函数:

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    Foo(ctx)
    defer func() {
        if r := recover(); r != nil {
            cancel()
        }
    }()

    panic("程序突然退出")
}
英文:

If your desire is that the process you initiated is killed when your program exits, then you can inject a context:

func Foo(ctx context.Context) {
    cmd := exec.CommandContext(ctx, "command that takes a long time")
    _ = cmd.Start()

    return
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    Foo(ctx)
    defer cancel()

    panic("program quit abruptly")
}

This code works by creating a context with a cancel function. This context is then sent to Foo and from there to the command function. When cancel is called, the context will be cancelled, causing the child process to be killed. To ensure that the context is cancelled, we defer the call to cancel, which ensures that the context is cancelled when the program exits for any reason, including a panic.

If your desire is to cancel only on panic, you can modify main slightly:

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    Foo(ctx)
    defer func() {
        if r := recover(); r != nil {
            cancel()
        }
    }()

    panic("program quit abruptly")
}

huangapple
  • 本文由 发表于 2022年10月27日 07:49:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/74215347.html
匿名

发表评论

匿名网友

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

确定