मैं किस प्रकार एक <दोषपूर्ण> प्रक्रिया को मार सकता हूं जिसका माता-पिता init है?


27

संचरण मेरे NAS पर रुक-रुक कर होता है। यदि मैं SIGTERM भेजता हूं, तो यह प्रक्रिया सूची से गायब नहीं <defunct>होता है और इसके बगल में एक लेबल दिखाई देता है। यदि मैं एक SIGKILL भेजता हूं, तो यह अभी भी गायब नहीं होता है और मैं माता-पिता को समाप्त नहीं कर सकता क्योंकि माता-पिता हैं init। जिस तरह से मैं इस प्रक्रिया से छुटकारा पा सकता हूं और ट्रांसमिशन को रिबूट करना है।

मुझे लगता है कि सबसे अच्छी बात यह है कि मैं कोशिश कर सकता हूं और ट्रांसमिशन को ठीक कर सकता हूं (और मैंने कोशिश की है), लेकिन मैं संकलन में एक नौसिखिया हूं और मैं यह सुनिश्चित करना चाहता था कि इससे पहले कि मैं इसके साथ खिलवाड़ करना शुरू करूं, मेरे टॉरेंट खत्म हो जाएं।


3
कोई भी स्पष्ट नहीं कह रहा है ... "init" के स्वामित्व वाली एक <दोषपूर्ण> प्रक्रिया असंभव होनी चाहिए! यह एक बहुत ही अजीब स्थिति है! क्या आपको यकीन है?
जोएलफैन

@JoelFan: मैं सिर्फ यह सुनिश्चित करने के लिए देख रहा था कि मैं कुछ महत्वपूर्ण नहीं भूल रहा हूं। लाश कि बच्चों को initबहुत जल्दी से दूर जाना चाहिए क्योंकि initसमय-समय पर बच्चों के इंतजार के रूप में इसके कई सामान्य कार्यों में <defunct>से एक ... एक ज़ोंबी के समान है?
डी। शेवले

1
कोई बात नहीं ... <defunct>ठीक एक ज़ोंबी के रूप में ही है। initअपने बच्चों पर इंतजार करेंगे ताकि सिद्धांत में ऐसा कभी न हो। मुझे आश्चर्य है कि अगर आप एक SIGCHLDको भेजते हैं तो क्या होता है init?
डी। शेवले

@JoelFan: हाँ, मुझे यकीन है। PPID के लिए मान 1 (init) था, इसलिए यह प्रक्रिया SIGKILL के लिए असंभव था।
एंडी ई

जवाबों:


35

आप एक <defunct>प्रक्रिया को नहीं मार सकते हैं (इसे ज़ोंबी प्रक्रिया भी कहा जाता है) क्योंकि यह पहले से ही मृत है। सिस्टम माता-पिता से बाहर निकलने की स्थिति को इकट्ठा करने के लिए ज़ोंबी प्रक्रिया रखता है। यदि माता-पिता ने बाहर निकलने की स्थिति एकत्र नहीं की, तो ज़ोंबी प्रक्रियाएं हमेशा के लिए आसपास रहेंगी। माता-पिता को मारने से उन ज़ोंबी प्रक्रियाओं से छुटकारा पाने का एकमात्र तरीका है। यदि माता-पिता के लिए यह अक्षम है तो आप केवल रिबूट कर सकते हैं।

ज़ोंबी प्रक्रियाओं में लगभग कोई परिवर्तन नहीं होता है इसलिए उन्हें लिंजर देने में कोई प्रदर्शन लागत नहीं होती है। हालांकि आमतौर पर आसपास ज़ोंबी प्रक्रियाओं का मतलब है कि आपके कुछ कार्यक्रमों में एक बग है। आमतौर पर सभी बच्चों को इकट्ठा करना चाहिए। अगर init के ज़ोंबी बच्चे हैं तो init (या somehwere बाकी लेकिन बग यह है) में एक बग है।

http://en.wikipedia.org/wiki/Zombie_process


9
initकभी भी ज़ोंबी बच्चे नहीं हो सकते। विकिपीडिया लेख से: जब कोई प्रक्रिया अपने माता-पिता को खो देती है, तो init उसका नया अभिभावक बन जाता है। Init समय-समय पर माता-पिता के रूप में init के साथ किसी भी लाश को निकालने के लिए प्रतीक्षा प्रणाली कॉल को निष्पादित करता है। में से एक initकी जिम्मेदारियों अनाथ और parentless लाश उठा रहा है।
डी। शेवले

14
@ D.Shawley: initहालांकि बग हो सकते हैं। Init प्रतिस्थापन runitमें बग है जो इस समस्या का कारण बनता है।
कैमह

2
init में एक बग के कारण शायद अयोग्य बच्चे हो सकते हैं, लेकिन यह हो सकता है। क्योंकि मैं अभी एक देख रहा हूं।
स्टूडियोज

यह कार्यक्रम है जिसे मैं टर्मिनल से चलाता था और विघटित स्थिति में प्रवेश करता था .. जैसा कि @ एलस्माना द्वारा समझाया गया था, जब मैंने टर्मिनल (माता-पिता) को बंद कर दिया था, तो कार्यक्रम स्वच्छ रूप से बाहर हो गया था।
एमके ..

6

ट्रांसमिशन सी स्रोत कोड को ठीक करने की कोशिश करने वाले किसी भी व्यक्ति को लाश और सिग्नल हैंडलर से बचने के लिए "डबल कांटा" चाल के बारे में पढ़ना चाहिए ... और इसका उपयोग स्मार्ट वेरिएडिक स्पॉन फ़ंक्शन के रूप में कैसे किया जा सकता है ( यूनिक्स में स्पैनिंग देखें )।

excerpt from: 
   "Spawning in Unix", http://lubutu.com/code/spawning-in-unix

Double fork
This trick lets you spawn processes whilst avoiding zombies, without 
installing any signal handler. The first process forks and waits for its 
child; the second process forks and immediately exits and is reaped;
the third process is adopted by init, and executes the desired program. 
All zombies accounted for, since init is always waiting.

if(fork() == 0) {
   if(fork() == 0) {
       execvp(file, argv);
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
wait(NULL);

1
डबल कांटा अपने माता-पिता को पीआईडी ​​1 में सेट करने के लिए कर्नेल को मजबूर करके ज़ोंबी प्रक्रियाओं को रोकता है, जो कि लाश को साफ करने के लिए माना जाता है। ऐसा लगता है कि ट्रांसमिशन पहले से ही ऐसा करता है, क्योंकि उसके माता-पिता पहले से ही प्रक्रिया 1 हैं।
21

1
यहां कई समस्याएं हैं। # 1: केवल माता-पिता को फोन करना चाहिए exit(3); बच्चों को _exit(2)इसके बजाय कॉल करना चाहिए (अन्यथा आपको अन्य मुद्दों के बीच कई stdio flushes मिलते हैं)। # 2: यदि यह विफल रहता है तो इसका execvp(3)उपयोग किया जा सकता perror(3)है। # 3: आपको signal(SIGCHLD, SIG_IGN)इस पूरे झमेले के बजाय बस इस्तेमाल करना चाहिए ।
केविन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.