2013-03-04 14 views
12

पर कोई प्रक्रिया मौजूद है या नहीं, यदि मेरे पास प्रक्रिया की पीआईडी ​​है, तो os.FindProcess प्रक्रिया के मौजूदा परीक्षण के लिए पर्याप्त है? मेरा मतलब है कि अगर यह err देता है तो क्या मुझे लगता है कि इसे समाप्त कर दिया गया है (या मारा गया)?जांचें कि

संपादित करें:

मैं सिर्फ एक आवरण समारोह के आसपास kill -s 0 (पुरानी शैली बैश प्रक्रिया परीक्षण) ने लिखा है। यह किसी भी समस्या के बिना काम करता है, लेकिन मैं अभी भी खुश हूँ अगर वहाँ अन्य समाधान इस समस्या .:

func checkPid(pid int) bool { 
    out, err := exec.Command("kill", "-s", "0", strconv.Itoa(pid)).CombinedOutput() 
    if err != nil { 
     log.Println(err) 
    } 

    if string(out) == "" { 
     return true // pid exist 
    } 
    return false 
} 

उत्तर

26

यहाँ अगर एक प्रक्रिया जीवित है देखने के लिए पारंपरिक यूनिक्स तरीका है - यह एक भेज 0 का संकेत (जैसे आपने अपने बैश उदाहरण के साथ किया था)।

kill(2) से:

If sig is 0, then no signal is sent, but error checking is still per‐ 
    formed; this can be used to check for the existence of a process ID or 
    process group ID. 

और जाओ

package main 

import (
    "fmt" 
    "log" 
    "os" 
    "strconv" 
    "syscall" 
) 

func main() { 
    for _, p := range os.Args[1:] { 
     pid, err := strconv.ParseInt(p, 10, 64) 
     if err != nil { 
      log.Fatal(err) 
     } 
     process, err := os.FindProcess(int(pid)) 
     if err != nil { 
      fmt.Printf("Failed to find process: %s\n", err) 
     } else { 
      err := process.Signal(syscall.Signal(0)) 
      fmt.Printf("process.Signal on pid %d returned: %v\n", pid, err) 
     } 

    } 
} 

में अनुवाद किया जब आप आप इस मिलता है, उस प्रक्रिया को 123 मर चुका है दिखा इसे चलाने, प्रक्रिया 1 जिंदा है, लेकिन नहीं आपके स्वामित्व में और 12606 की प्रक्रिया जिंदा है और आपके स्वामित्व में है।

$ ./kill 1 $$ 123 
process.Signal on pid 1 returned: operation not permitted 
process.Signal on pid 12606 returned: <nil> 
process.Signal on pid 123 returned: no such process 
+0

यह बात है! गो रास्ता दिखाने के लिए धन्यवाद :) –

+0

आप 'int64' में क्यों पार्स कर रहे हैं। 'एटोई' बेहतर नहीं होगा ('FindProcess'' में कोई प्रकार परिवर्तित नहीं होगा? – tjameson

+0

हाँ आप सही हैं 'एटोई' बेहतर होगा। मुझे लगता है कि मैंने हाल ही में 'ParseInt' का उपयोग किया और इसके बारे में भूल गया! –

5
सिस्टम (Linux, FreeBSD, आदि) की तरह

यूनिक्स पर करने के लिए (जाने पुस्तकालयों के साथ किया जाता है) os.FindProcess होगा कभी त्रुटि न करें। मुझे नहीं पता कि विंडोज पर क्या होता है। इसका मतलब यह है कि आप तब तक नहीं जान पाएंगे जब तक कि पीआईडी ​​सही नहीं है जब तक कि आप किसी के लिए * os.Process का उपयोग करने का प्रयास न करें।

आप कोड here पर देख सकते हैं।

+0

आप सही हैं।यह हमेशा सच देता है, मुझे काम-आसपास मिल गया है (ऊपर मेरा संपादन देखें) –

+0

विंडोज 10 पर अपने अनुभव से, ओ। फिंडप्रोसेस 'त्रुटि देता है अगर दिए गए पीआईडी ​​के साथ प्रक्रिया नहीं चल रही है। – Kerrmiter

1

यदि पहले ज्ञात पिड सिस्टम में नहीं पाया जाता है (कार्य करने के बारे में सुनिश्चित नहीं है), तो इसका मतलब है कि प्रक्रिया निश्चित रूप से समाप्त हो गई है और इसमें शामिल हो गया है (यूनिक्स पर, wait call के साथ) भी।

लेकिन अन्य तरीकों के आसपास जरूरी नहीं है। सिर्फ इसलिए कि एक पिड मौजूद है, यह गारंटी नहीं देता है कि यह पहले की तरह ही प्रक्रिया है। उदाहरण के लिए मानक लिनक्स में केवल 65535 वैध पिड्स हैं, और जब वे रैप-आस-पास होते हैं तो वे फिर से उपयोग कर सकते हैं। हालांकि, यदि आप व्यावहारिक उद्देश्यों के लिए अक्सर उचित रूप से जांच करते हैं, तो आपको इसकी परवाह करने की आवश्यकता नहीं है (जब तक कि गलत नई प्रक्रिया के ढक्कन को सुरक्षा भेद्यता या कुछ और महत्वपूर्ण नहीं है, जो कोई जानबूझकर दुर्भावनापूर्ण रूप से ट्रिगर करने का प्रयास कर सकता है प्रयोजनों)। (अपने अधिकार स्तंभों पर और संबंधित प्रश्न)

संबंधित लिंक:

+0

मेरी इच्छा है कि मैं एक से अधिक बार ऊपर उठा सकता हूं। अवलोकन कि पिड्स का पुन: उपयोग किया जाता है, _critical_ किसी भी व्यक्ति के लिए आधुनिक हार्डवेयर पर प्रक्रियाओं की भरोसेमंद निगरानी करने की इच्छा रखने के लिए है: यदि कुछ गलत व्यवहार और श्वसन हो रहा है, तो पिड नेमस्पेस जल्दी समाप्त हो जाएगा। चूंकि थ्रेड आईडी एक ही नामस्थान में प्रक्रिया आईडी के रूप में हैं, इसलिए भारी थ्रेडेड प्रक्रिया समस्या को बढ़ा देती है। – Mark

+1

उल्लेख करने के लिए भूल गए ... यदि आपको अतिरिक्त आत्मविश्वास की आवश्यकता है, तो सत्यापित करें कि [प्रक्रिया प्रारंभ समय] (http://unix.stackexchange.com/a/7871/158521) $ pid के लिए चेक के बीच नहीं बदला गया है। यदि यह है, तो यह एक अलग प्रक्रिया है। यदि नहीं, तो यह _highly_ एक अलग प्रक्रिया होने की संभावना नहीं है। – Mark

+0

"अत्यधिक संभावना" से आपका क्या मतलब है? किस परिस्थिति में यह * एक अलग प्रक्रिया नहीं हो सकती है? मान लीजिए कि यह प्रक्रिया एक यूनिट की तुलना में ज़िंदा रहती है, जो भी शुरुआती समय में मापा जाता है (इसलिए पीआईडी ​​रैपरराउंड के साथ एक त्वरित मर/पुनरुत्थान चेकर को भ्रमित नहीं करता है), केवल एक ही परिस्थिति जिसे मैं सोच सकता हूं वह स्टार्ट-टाइम रैपरराउंड है। क्या वहां कुछ हैं? –

2

आप भी syscall.Kill का उपयोग कर सकते हैं। यह कम कोड की मात्रा है।

killErr := syscall.Kill(pid, syscall.Signal(0)) 
procExists := killErr == nil 
+0

द्वारा कटाई नहीं किया गया है [निक क्रेग-वुड के उत्तर] (http://stackoverflow.com/a/15210305/55504) से नोट को छोड़कर कि एक गैर-शून्य त्रुटि मौजूदा प्रक्रियाओं के लिए वापस किया जा सकता है। आपको अधिक शामिल सशर्त होना चाहिए (शायद 'err == nil || err == syscall.EPERM', शायद अधिक)। –

0

विंडोज os.FindProcess() का परिणाम जाँच पर अगर प्रक्रिया चल रहा है की जाँच करने के लिए पर्याप्त हो रहा है।

func isProcessRunning(pid int) bool { 
    _, err = os.FindProcess(pid) 
    if err != nil { 
     return false 
    } 
    if runtime.GOOS == "windows" { 
     return true 
    } 
    return false // further checking for other systems then Windows is not supported here 
} 
संबंधित मुद्दे