2013-08-07 46 views
9

Tôi muốn triển khai "trình bao bọc quy trình" trong Go. Về cơ bản những gì nó sẽ làm, là khởi động một quá trình (cho phép nói một máy chủ nút) và giám sát nó (bắt tín hiệu như SIGKILL, SIGTERM ...)Tín hiệu bắt Golang

Tôi nghĩ cách làm là khởi động máy chủ nút trong khi di chuyển thói quen sử dụng syscall.Exec:

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

Sau đó, tôi muốn nắm bắt mọi tín hiệu có thể được tạo ra bởi các lệnh được thực hiện bởi syscall. Tôi khá mới để Go, bất kỳ trợ giúp sẽ được đánh giá cao.

+0

[Xem thêm] (http://stackoverflow.com/q/11268943/720999). – kostix

Trả lời

30

Có ba cách để thực hiện một chương trình tại Gò:

  1. syscall gói với syscall.Exec, syscall.ForkExec, syscall.StartProcess
  2. os gói với os.StartProcess
  3. os/exec gói với exec.Command

syscall.StartProcess là cấp thấp. Nó trả về một số uintptr làm xử lý.

os.StartProcess cung cấp cho bạn cấu trúc os.Process đẹp mà bạn có thể gọi Signal vào. os/exec cung cấp cho bạn io.ReaderWriter để sử dụng trên đường ống. Cả hai đều sử dụng syscall nội bộ.

Tín hiệu đọc được gửi từ quy trình khác với quy trình của bạn có vẻ hơi phức tạp một chút. Nếu có thể, syscall sẽ có thể thực hiện được. Tôi không thấy bất cứ điều gì rõ ràng trong các gói cấp cao hơn.

Tiếp nhận một tín hiệu bạn có thể sử dụng signal.Notify như thế này:

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

Bạn chỉ cần thay đổi các tín hiệu bạn quan tâm lắng nghe. Nếu bạn không chỉ định tín hiệu, nó sẽ bắt tất cả các tín hiệu có thể chụp được.

Bạn sẽ sử dụng syscall.Kill hoặc Process.Signal để ánh xạ tín hiệu. Bạn có thể lấy pid từ Process.Pid hoặc kết quả từ syscall.StartProcess.

+0

Thx Tôi sẽ thử nó. Ý tưởng là để có wrapper này theo dõi bởi mới nổi, nó sẽ chỉ được sử dụng để theo dõi những gì đã xảy ra – rmonjo

+0

Ok tôi có thể bắt tín hiệu được nhập vào chương trình (nếu tôi làm^C ví dụ) nhưng không thể nhận được tín hiệu tạo ra bởi chương trình của tôi được thực hiện bởi syscall. Bất cứ suy nghĩ nào ? – rmonjo

+0

@rmonjo Bạn đang cố gắng nhận tín hiệu được gửi * từ * chương trình của bạn hoặc * đến *? – Luke

16

Bạn có thể sử dụng 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 
     } 
    }() 
    // ... 
} 
Các vấn đề liên quan