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でプログラムを実行する方法は3つあります。
syscall
パッケージ syscall.Exec 、 syscall.ForkExec 、 syscall.StartProcessos
パッケージ os.StartProcessos/exec
パッケージ exec.Commandsyscall.StartProcess は低レベルです。 uintptr
をハンドルとして返します。
os.StartProcess
は、呼び出しが可能なos.Process
構造体 Signal onを提供します。 os/exec
は、パイプで使用するio.ReaderWriter
を提供します。どちらも内部でsyscall
を使用します。
送信されたシグナルを読み取るfrom自分以外のプロセスは少し難しいようです。可能であれば、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 を使用して信号をマッピングします。 pidはProcess.Pid
から、または syscall.StartProcess から結果として取得できます。
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
}
}()
// ...
}