2013-08-07 115 views
9

我想在Go中實現一個「流程包裝器」。基本上它會做什麼,是啓動一個進程(可以說一個節點服務器)並監控它(捕獲信號像SIGKILL,SIGTERM ...)Golang捕獲信號

我認爲做的方法是啓動節點服務器常規使用syscall.Exec

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

然後我想捕捉由syscall執行該命令產生的每個可能的信號。我對Go很新,任何幫助將不勝感激。

+0

[參見](http://stackoverflow.com/q/11268943/720999)。 – kostix

回答

30

有圍棋執行程序的方式有三種:

  1. syscallsyscall.Execsyscall.ForkExecsyscall.StartProcess
  2. osos.StartProcess
  3. os/execexec.Command

syscall.StartProcess是低級別。它返回一個uintptr作爲句柄。

os.StartProcess給你一個不錯的os.Process結構,你可以調用Signalos/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.Pidsyscall.StartProcess得到pid。

+0

Thx我會嘗試。這個想法是讓這個包裝被暴發戶監控,它只會被用來跟蹤發生了什麼 – rmonjo

+0

好吧,我可以捕獲輸入到程序中的信號(例如,如果我做^ C例如)但不能產生信號由我的程序由系統調用執行。任何想法 ? – rmonjo

+0

@rmonjo你試圖捕獲從你的程序發送*到*發送的信號嗎? – Luke

16

您可以使用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 
     } 
    }() 
    // ... 
}