2011-12-30 20 views
9

मैं एक सर्वर कोड पर काम कर रहा हूं जो fork() का उपयोग करता है और बाल प्रक्रियाओं को बनाने के लिए निष्पादित करता है। fork()CHILD सिग्नल पकड़ा गया है जब बच्चे की पीआईडी ​​पंजीकृत है।क्या एक किल सिग्नल तुरंत प्रक्रिया से बाहर निकलता है?

यदि सर्वर को रुकने की ज़रूरत है, तो अंततः एक किल सिग्नल के साथ सभी कार्यक्रम मारे जाते हैं। अब, यह सभी पंजीकृत पीआईडी ​​के माध्यम से पुन: प्रयास करने और पीआईडी ​​को हटाने के लिए बच्चे सिग्नल हैंडलर की प्रतीक्षा के माध्यम से काम करता है। अगर बच्चा प्रोग्राम ठीक से बाहर नहीं निकलता तो यह असफल हो जाएगा। इसलिए मैं kill का उपयोग waitpid के साथ संयोजन में करना चाहता हूं ताकि यह सुनिश्चित किया जा सके कि पीआईडी ​​सूची साफ़ हो और लॉग इन करें और अन्यथा कुछ अन्य सामान करें।

पर विचार अगले कोड नमूना:

kill(pid, SIGKILL); 
waitpid(pid, NULL, WNOHANG); 

अंश waitpid(2) से:

waitpid(): सफलता पर, बच्चे जिसका राज्य बदल गया है की प्रक्रिया आईडी रिटर्न; अगर WNOHANG निर्दिष्ट किया गया था और एक या अधिक बच्चा (ren) पिड द्वारा निर्दिष्ट किया गया है, लेकिन अभी तक राज्य नहीं बदला है, तो 0 वापस कर दिया गया है। त्रुटि पर, -1 वापस आ गया है।

क्या pid द्वारा दी गई प्रक्रिया हमेशा अगले कार्य में आने से पहले चली जाती है? उपरोक्त मामले में waitpid हमेशा -1 वापस करेगा?

+2

एक किल सिग्नल बल्कि क्रूर है, क्यों INT या HUP नहीं? और, 'kill' syscall का रिटर्न कोड क्या है? – fge

+0

"चिल्ड सिग्नल हैंडलर के लिए प्रतीक्षा ..." - सिग्कील के लिए कोई सिग्नल हैंडलर नहीं है, आपको पता है? सिगस्टॉप और सिगकिल को छोड़कर सभी संकेत 'सिग्नेक्शन' द्वारा सेट किए गए हैं (इसलिए उदाहरण के लिए एक हैंडलर का आह्वान करें), या डिफ़ॉल्ट। सिगस्टॉप बस बंद हो जाता है, और सिगकिल बस प्रक्रिया को मार देता है। हमेशा। कोई हैंडलिंग या सशर्त नहीं है। (अपवाद यह है कि 'kill' syscall विफल रहता है क्योंकि आपके पास पर्याप्त अधिकार नहीं हैं।) – Damon

+0

@Damon:' SIGKILL' को गंतव्य प्रक्रिया द्वारा अनदेखा नहीं किया जा सकता है, ठीक है। लेकिन सवाल/समस्या नहीं है।स्रोत प्रक्रिया के संदर्भ में सिग्नल का मूल्यांकन (कर्नेल द्वारा) स्रोत प्रक्रिया पर 'मार (2)' सिस्टम कॉल वापस आ सकता है। 'मारो (2)' मूल रूप से एक बहुत ही सरल असीमित संचार है और सभी प्रभावों के साथ इस तरह व्यवहार किया जाना चाहिए। –

उत्तर

8

क्या अगले कार्य से पहले पिड द्वारा दी गई प्रक्रिया हमेशा चली जाती है?

इसके लिए कोई गारंटी नहीं है। एक मल्टीप्रोसेसर पर आपकी प्रक्रिया सीपीयू 0 पर हो सकती है जबकि मारे गए प्रक्रिया के लिए कर्नेल में क्लीनअप सीपीयू 1 पर होता है। यह एक शास्त्रीय दौड़-स्थिति है। सिंगलकोर प्रोसेसर पर भी इसके लिए कोई गारंटी नहीं है।

क्या प्रतीक्षाकर्ता हमेशा उपरोक्त मामले में -1 लौटाएगा?

चूंकि यह दौड़ की स्थिति है - ज्यादातर मामलों में यह शायद होगा। लेकिन कोई गारंटी नहीं है।


जब से तुम स्थिति में कोई दिलचस्पी नहीं कर रहे हैं, इस semicode अपने मामले में और अधिक उपयुक्त हो सकता है:

// kill all childs 
foreach(pid from pidlist) 
    kill(pid, SIGKILL); 

// gather results - remove zombies 
while(not_empty(pidlist)) 
    pid = waitpid(-1, NULL, WNOHANG); 
    if(pid > 0) 
     remove_list_item(pidlist, pid); 
    else if(pid == 0) 
     sleep(1); 
    else 
     break; 
+0

स्पष्टीकरण के लिए धन्यवाद, मैं सुझाए गए कोड का उपयोग नहीं कर पाऊंगा क्योंकि सिग्चील्ड हैंडलर आइटम को पिडलिस्ट से हटा देता है। यह मुझे विकल्प पर छोड़ देता है: जांचें कि प्रक्रिया चल रही है या नहीं, अगर नहीं, तो अन्यथा मार डालें। – Lekensteyn

+0

बस 'WNOHANG' ध्वज हटा दें और आपका कोड अपेक्षित के रूप में काम करेगा। –

+0

@Lekensteyn: यदि पहले से ही एक सिग्चाल्ड हैंडलर है जो एक सूची अद्यतन करता है, तो यह हैंडलर ज़ोंबी प्रक्रिया को हटाने के लिए 'प्रतीक्षापिड' को कॉल कर सकता है। फिर 'जबकि' लूप को केवल ए के लिए इंतजार करना होगा) सभी प्रक्रियाओं को मृत और दफन किया गया है या बी) सुरक्षा के लिए कुछ समय समाप्ति। –

4

KILL संकेत हैंडलर की मौत हो गई प्रक्रियाओं सीपीयू समय के दौरान चलेंगे। यह आपके waitpid कॉल से काफी बाद में है, खासकर लोड सिस्टम पर, इसलिए waitpid बहुत अच्छी तरह से 0

संबंधित मुद्दे