2013-08-07 12 views
9

मैं गो में एक "प्रक्रिया रैपर" लागू करना चाहता हूं। असल में यह क्या करेगा, एक प्रक्रिया लॉन्च करें (एक नोड सर्वर कहें) और इसकी निगरानी करें (सिगकिल, सिग्टरएम जैसे सिग्नल सिग्नल ...)गोलांग पकड़ संकेत

मुझे लगता है कि ऐसा करने का तरीका नोड सर्वर को लॉन्च करना है दिनचर्या syscall.Exec का उपयोग कर:

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

तब मैं आदेश syscall द्वारा निष्पादित द्वारा उत्पन्न हर संभव संकेतों को पकड़ने के लिए चाहते हैं। मैं जाने के लिए बहुत नया हूं, किसी भी मदद की सराहना की जाएगी।

+0

[भी देखें] (http://stackoverflow.com/q/11268943/720999)। – kostix

उत्तर

30

वहाँ जाओ में एक कार्यक्रम को क्रियान्वित करने के तीन तरीके हैं:

  1. syscallsyscall.Exec, syscall.ForkExec, syscall.StartProcess
  2. os पैकेज के साथ साथ पैकेज os.StartProcess
  3. os/exec पैकेज exec.Command साथ

syscall.StartProcess कम स्तर है। यह एक हैंडल के रूप में uintptr देता है।

os.StartProcess आपको एक अच्छा os.Process संरचना देता है जिसे आप Signal पर कॉल कर सकते हैं। os/exec आपको पाइप पर उपयोग करने के लिए io.ReaderWriter देता है। दोनों आंतरिक रूप से syscall का उपयोग करते हैं।

पढ़ना सिग्नल से भेजा गया एक प्रक्रिया आपके अलावा कुछ और मुश्किल लगती है। यदि यह संभव था, syscall ऐसा करने में सक्षम होगा। मुझे उच्च स्तर के पैकेज में कुछ भी स्पष्ट नहीं दिख रहा है।

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

तुम बस संकेतों आप को सुनने में रुचि रखते हैं को बदलने की जरूरत:

एक संकेत आप signal.Notify इस तरह उपयोग कर सकते हैं प्राप्त करने के लिए। यदि आप सिग्नल निर्दिष्ट नहीं करते हैं, तो यह उन सभी सिग्नल को पकड़ लेगा जिन्हें कैप्चर किया जा सकता है।

सिग्नल मैप करने के लिए आप syscall.Kill या Process.Signal का उपयोग करेंगे। आप Process.Pid से या syscall.StartProcess से परिणाम प्राप्त कर सकते हैं।

+0

Thx मैं इसे आज़माउंगा। विचार यह है कि इस रैपर को अपस्टार्ट द्वारा निगरानी रखी जाए, इसका उपयोग – rmonjo

+0

पर हुआ ट्रैक का ट्रैक रखने के लिए किया जाएगा ठीक है, मैं प्रोग्राम में इनपुट किए गए संकेतों को पकड़ सकता हूं (यदि मैं उदाहरण के लिए^सी करता हूं) लेकिन सिग्नल उत्पन्न नहीं हो सकते syscall द्वारा निष्पादित मेरे कार्यक्रम द्वारा। कोई सोच ? – 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 
     } 
    }() 
    // ... 
}