英文:
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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论