Golang 捕捉信号

标签 go signals system-calls

我想在 Go 中实现一个“流程包装器”。基本上它会做的是启动一个进程(比如说一个节点服务器)并监控它(捕获信号,如 SIGKILL、SIGTERM ...)

我认为这样做的方法是使用 syscall.Exec 在 go 例程中启动节点服务器:

func launchCmd(path string, args []string) {
  err := syscall.Exec(path, args, os.Environ())
  if err != nil {
    panic(err)
  }
}

然后我想捕获由 syscall 执行的命令生成的所有可能的信号。我对 Go 很陌生,任何帮助将不胜感激。

最佳答案

Go 中有三种执行程序的方式:

  1. syscall 包与 syscall.Exec , syscall.ForkExec , syscall.StartProcess
  2. os 包与 os.StartProcess
  3. os/exec 包与 exec.Command

syscall.StartProcess是低水平。它返回一个 uintptr 作为句柄。

os.StartProcess 为您提供了一个不错的 os.Process 结构,您可以调用它 Signal上。 os/exec 为您提供 io.ReaderWriter 以在管道上使用。两者都在内部使用 syscall

读取您自己的进程以外的进程发送的信号似乎有点棘手。如果可能,syscall 将能够做到。我在更高级别的包中看不到任何明显的东西。

要接收信号,您可以使用 signal.Notify像这样:

sigc := make(chan os.Signal, 1)
signal.Notify(sigc,
    syscall.SIGHUP,
    syscall.SIGINT,
    syscall.SIGTERM,
    syscall.SIGQUIT)
go func() {
    s := <-sigc
    // ... do something ...
}()

您只需要更改您有兴趣收听的信号即可。如果不指定信号,它将捕获所有可以捕获的信号。

你会使用 syscall.KillProcess.Signal映射信号。您可以从 Process.Pid 或从 syscall.StartProcess 获取 pid .

关于Golang 捕捉信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18106749/

相关文章:

ruby - Ruby 中的进程间信号处理

javascript - 一种从 Node.js 调用 execl、execle、execlp、execv、execvP 或 execvp 的方法

linux - 了解 libc.a 中的简单 Linux 系统调用

go - 如何在 Go 中对这些类型建模

c - sigaction 只处理一次信号

c - 使用 sleep 和 select 信号

c - 在 C 中重定向输出时杀死并没有真正杀死

Go 返回错误以及函数的接口(interface)

go - Angular 5 和 Go 网络服务

go - Go的SSH客户端和AIX上的PTY