Golang 捕获信号

问题描述 投票:0回答:4

我想在 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 signals system-calls
4个回答
73
投票

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

  1. syscall
    包含 syscall.Execsyscall.ForkExecsyscall.StartProcess
  2. 的软件包
  3. os
    带有 os.StartProcess
  4. 的包
  5. os/exec
    包含 exec.Command
  6. 的软件包

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.Kill

Process.Signal 来映射信号。您可以从 Process.Pid 或从

syscall.StartProcess
获取 pid。


41
投票
signal.Notify

: import ( "os" "os/signal" "syscall" ) func main() { signalChannel := make(chan os.Signal, 2) signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) go func() { sig := <-signalChannel switch sig { case os.Interrupt: //handle SIGINT case syscall.SIGTERM: //handle SIGTERM } }() // ... }



2
投票


0
投票

go run main.go

独立构建和运行它:

go build main.go ./main

	
© www.soinside.com 2019 - 2024. All rights reserved.