终止过程:上下文取消和终止信号之间的区别


func main() {
ctx, cancel := context.WithCancel(context.Background())
cmd := exec.CommandContext(ctx, "sleep", "1000")
go func() {
time.Sleep(2 * time.Second)
//cmd.Process.Signal(os.Kill)
//cmd.Process.Signal(os.Interrupt)
cancel()
}()
if err := cmd.Run(); err != nil {
fmt.Println(err.Error())
}
fmt.Println("Finishing...")
}

cancelSignal(os.Kill)之间有什么区别吗?它们会导致相同的错误。

如何区分终止信号和因错误而终止?仅通过检查err.Error() == "signal: killed"

exec的文档。CommandContext为您提供了这个问题的答案:

如果上下文在命令自行完成之前完成,则提供的上下文用于终止进程(通过调用os.process.kill(。

反过来,os。Process.Kill调用操作系统特定的kill()函数,如下所示用于posix:

func (p *Process) kill() error {
return p.Signal(Kill)
}

所以两者最终都调用了Signal(os.Kill)

至于如何区分,你有两个基本选项:

  • 解析可能很脆弱的错误(尽管直接检查signal: killed也不算太糟
  • 检查退出代码,当被SIGKILL终止时,应该为137

最新更新