Golang捕获信号

rmo*_*njo 19 signals system-calls go

我想在Go中实现一个"进程包装器".基本上它会做什么,是启动一个进程(比如节点服务器)并监视它(捕获信号,如SIGKILL,SIGTERM ...)

我认为要做的方法是使用syscall.Exec以下命令在go例程中启动节点服务器:

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

然后我想捕获由执行的命令生成的每个可能的信号syscall.我是Go的新手,任何帮助都会受到赞赏.

Luk*_*uke 45

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结构,你可以调用信号.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 ...
}()
Run Code Online (Sandbox Code Playgroud)

你只需要改变你有兴趣听的信号.如果您没有指定信号,它将捕获所有可捕获的信号.

您可以使用syscall.KillProcess.Signal来映射信号.您可以Process.Pidsyscall.StartProcess获取pid 或作为结果.


Bab*_*aba 22

你可以使用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
        }
    }()
    // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 嗨 Baba,为什么要制作大小为 2 的缓冲通道? (4认同)