एक निर्बाध प्रक्रिया क्या है?


156

कभी-कभी जब भी मैं लिनक्स में कोई प्रोग्राम लिखता हूं और यह किसी प्रकार के बग के कारण क्रैश हो जाता है, तो यह एक अबाधित प्रक्रिया बन जाएगी और जब तक मैं अपना कंप्यूटर (यहां तक ​​कि अगर मैं लॉग आउट करता हूं) को पुनरारंभ करने तक हमेशा चलता रहता हूं। मेरे प्रश्न हैं:

  • क्या एक प्रक्रिया के कारण अबाधित हो जाता है?
  • मैं ऐसा होने से कैसे रोकूं?
  • यह शायद एक गूंगा सवाल है, लेकिन क्या मेरे कंप्यूटर को पुनरारंभ किए बिना इसे बाधित करने का कोई तरीका है?

क्या यह संभव है कि एक प्रक्रिया को शुरू करने के लिए एक कार्यक्रम लिखा जा सकता है जो एक TASK_UNINTERUPTIBLEराज्य में चला जाता है जब भी सिस्टम निष्क्रिय स्थिति में नहीं होता है, जिससे जबरन डेटा एकत्र किया जाता है, एक बार सुपर उपयोगकर्ता के बाहर निकलने के लिए संचार करने की प्रतीक्षा करता है? यह हैकर्स के लिए सूचना प्राप्त करने, ज़ोंबी राज्य में लौटने और निष्क्रिय नेटवर्क पर सूचना प्रसारित करने के लिए एक सोने की खान होगी। कुछ लोग यह तर्क दे सकते हैं कि यह Blackdoorकिसी भी प्रणाली में वांछित शक्तियों के लिए प्रवेश करने और बाहर निकलने के लिए बनाने का एक तरीका है । मेरा दृढ़ता से मानना ​​है कि इस खामी को 'TASK_UNINTERUPTIB
Nuuwski

2
कृपया कोड साझा करें?
फिर से

जवाबों:


198

एक निर्बाध प्रक्रिया एक प्रक्रिया है जो एक सिस्टम कॉल (कर्नेल फ़ंक्शन) में होती है जिसे सिग्नल द्वारा बाधित नहीं किया जा सकता है।

यह समझने के लिए कि इसका क्या मतलब है, आपको एक रुकावट प्रणाली कॉल की अवधारणा को समझने की आवश्यकता है। क्लासिक उदाहरण है read()। यह एक सिस्टम कॉल है जिसमें एक लंबा समय (सेकंड) लग सकता है क्योंकि इसमें संभावित रूप से हार्ड ड्राइव या घूमते हुए सिर शामिल हो सकते हैं। इस समय के दौरान, अधिकांश प्रक्रिया सो रही होगी, हार्डवेयर पर अवरुद्ध।

जब प्रक्रिया सिस्टम कॉल में सो रही होती है, तो यह एक यूनिक्स एसिंक्रोनस सिग्नल (जैसे, SIGTERM) प्राप्त कर सकता है, फिर निम्न होता है:

  • सिस्टम कॉल समय से पहले बाहर हो जाता है, और वापस लौटने के लिए सेट किया जाता है-उपयोगकर्ता के लिए।
  • सिग्नल हैंडलर को निष्पादित किया जाता है।
  • यदि प्रक्रिया अभी भी चल रही है, तो इसे सिस्टम कॉल से रिटर्न वैल्यू मिलती है, और यह फिर से वही कॉल कर सकता है।

सिस्टम कॉल से जल्दी लौटना उपयोगकर्ता स्पेस कोड को सिग्नल के जवाब में तुरंत अपने व्यवहार को बदलने में सक्षम बनाता है। उदाहरण के लिए, SIGINT या SIGTERM की प्रतिक्रिया में सफाई को समाप्त करना।

दूसरी ओर, कुछ सिस्टम कॉल को इस तरह से बाधित नहीं होने दिया जाता है। यदि सिस्टम किसी कारण से स्टालों को बुलाता है, तो प्रक्रिया अनिश्चित रूप से इस अनजान स्थिति में बनी रह सकती है।

LWN ने एक अच्छा लेख चलाया जिसने जुलाई में इस विषय को छुआ।

मूल प्रश्न का उत्तर देने के लिए:

  • इसे होने से कैसे रोकें: यह पता लगाएं कि कौन सा ड्राइवर आपको परेशान कर रहा है, और या तो उपयोग करना बंद करें, या कर्नेल हैकर बनें और इसे ठीक करें।

  • रिबूट किए बिना एक निर्बाध प्रक्रिया को कैसे मारें: किसी तरह सिस्टम कॉल को समाप्त करें। पावर स्विच से टकराने के बिना अक्सर ऐसा करने का सबसे प्रभावी तरीका पावर कॉर्ड को खींचना है। आप कर्नेल हैकर भी बन सकते हैं और ड्राइवर को TASK_KILLABLE का उपयोग कर सकते हैं, जैसा कि LWN लेख में बताया गया है।


31
मैंने अपने लैपटॉप पर पावर कॉर्ड खींचा और यह दुख की बात नहीं है। ;-)
दोपहर

1
यह EAGTR के बजाय EINTR नहीं है? यह भी पढ़ें () रिटर्न -1 और इरनो त्रुटि पर सेट है।
घातक

2
@Dexter: आप वास्तव में इस बिंदु को याद कर रहे हैं। पढ़ें LWN लेख: lwn.net/Articles/288056 । उन समस्याओं के कारण आलसी डिवाइस ड्राइवर प्रोग्रामर होते हैं, और उन्हें डिवाइस ड्राइवर कोड में ठीक करने की आवश्यकता होती है।
ddaa

4
@ddaa "यूनिक्स परंपरा (और इस प्रकार लगभग सभी एप्लिकेशन) का मानना ​​है कि फ़ाइल स्टोर नॉन सिग्नल को बाधित करने के लिए लिखता है। यह उस गारंटी को बदलने के लिए सुरक्षित या व्यावहारिक नहीं होगा।" -> यह वास्तव में इस IMO का सबसे गलत हिस्सा है। बस ड्राइवर के पढ़ने / लिखने के अनुरोध को बाधित करें, और जब वास्तविक डिवाइस (हार्ड डिस्क / नेटवर्क कार्ड / आदि) डेटा बचाता है, तो इसे अनदेखा करें। एक ओएस कर्नेल को इस तरह से बनाया जाना चाहिए कि कोई भी डेवलपर इसे खराब न कर सके।
डेक्सटर

2
@ddaa मुझे पता है कि लिनक्स एक माइक्रोकर्नेल नहीं है, हालांकि मुझे यकीन नहीं है कि मेरी टिप्पणी का क्या हिस्सा इससे संबंधित है ... और फिर, क्या आपकी टिप्पणी का मतलब यह है कि माइक्रोक्राइब ओएस को उन "निर्बाध" प्रक्रियाओं के साथ कोई समस्या नहीं है? क्योंकि अगर ऐसा नहीं होता है, तो शायद मेरे लिए माइक्रो कर्नेल प्रशंसक बनने का समय आ गया है ...: D
Dexter

49

जब कोई प्रक्रिया उपयोगकर्ता मोड पर होती है, तो इसे किसी भी समय बाधित किया जा सकता है (कर्नेल मोड पर स्विच करना)। जब कर्नेल उपयोगकर्ता मोड में लौटता है, तो यह जांचता है कि क्या कोई सिग्नल लंबित हैं (इनमें से जो प्रक्रिया को मारने के लिए उपयोग किए जाते हैं, जैसे कि SIGTERMऔर SIGKILL)। इसका अर्थ है कि उपयोगकर्ता मोड पर लौटने पर ही किसी प्रक्रिया को मारा जा सकता है।

कर्नेल मोड में किसी प्रक्रिया को नहीं मारा जा सकता है, यह एक ही मशीन में अन्य सभी प्रक्रियाओं द्वारा उपयोग किए जाने वाले कर्नेल संरचनाओं को संभावित रूप से दूषित कर सकता है (उसी तरह एक धागा को मारने से संभवतः उसी प्रक्रिया में अन्य थ्रेड्स द्वारा उपयोग किए गए भ्रष्ट डेटा संरचनाएं हो सकती हैं) ।

जब कर्नेल को कुछ ऐसा करने की आवश्यकता होती है, जिसमें एक लंबा समय लग सकता है (किसी अन्य प्रक्रिया द्वारा लिखी गई पाइप पर प्रतीक्षा करना या हार्डवेयर के लिए कुछ करने की प्रतीक्षा करना, उदाहरण के लिए), यह खुद को सोने के रूप में चिह्नित करके और दूसरे को स्विच करने के लिए अनुसूचक को कॉल करके सोता है। प्रक्रिया (यदि कोई गैर-नींद की प्रक्रिया नहीं है, तो यह एक "डमी" प्रक्रिया में बदल जाता है जो सीपीयू को थोड़ा धीमा करने के लिए कहता है और एक लूप में बैठता है - निष्क्रिय लूप)।

यदि किसी सिग्नल को नींद की प्रक्रिया में भेजा जाता है, तो इसे उपयोगकर्ता के स्थान पर लौटने से पहले जागना होगा और इस प्रकार लंबित सिग्नल को संसाधित करना होगा। यहाँ हम दो मुख्य प्रकारों के बीच अंतर रखते हैं:

  • TASK_INTERRUPTIBLE, बीच में नींद। यदि इस झंडे के साथ कोई कार्य चिह्नित है, तो यह सो रहा है, लेकिन संकेतों द्वारा जगाया जा सकता है। इसका मतलब यह है कि कोड जो कार्य को सोने के रूप में चिह्नित करता है, एक संभावित संकेत की उम्मीद कर रहा है, और इसके जागने के बाद इसके लिए जांच करेगा और सिस्टम कॉल से वापस आ जाएगा। सिग्नल हैंडल होने के बाद, सिस्टम कॉल संभावित रूप से स्वचालित रूप से पुनरारंभ हो सकता है (और मैं इस बात पर विवरण में नहीं जाऊंगा कि यह कैसे काम करता है)।
  • TASK_UNINTERRUPTIBLEनिर्बाध नींद। यदि किसी कार्य को इस ध्वज के साथ चिह्नित किया जाता है, तो यह अपेक्षा नहीं करता है कि जो कुछ भी इसके लिए इंतजार कर रहा है, उसके अलावा किसी और चीज से जागृत किया जाए, क्योंकि इसे आसानी से फिर से शुरू नहीं किया जा सकता है, या क्योंकि प्रोग्राम सिस्टम कॉल को परमाणु होने की उम्मीद कर रहे हैं। यह बहुत कम ज्ञात नींद के लिए भी इस्तेमाल किया जा सकता है।

TASK_KILLABLE (डीडीए के जवाब से जुड़े LWN लेख में उल्लिखित) एक नया संस्करण है।

यह आपके पहले प्रश्न का उत्तर देता है। आपके दूसरे प्रश्न के रूप में: आप अबाधित नींद से बच नहीं सकते हैं, वे एक सामान्य बात है (यह होता है, उदाहरण के लिए, जब भी कोई प्रक्रिया डिस्क से / से लिखती / पढ़ती है); हालाँकि, उन्हें केवल एक सेकंड के कुछ अंश तक चलना चाहिए। यदि वे बहुत लंबे समय तक चलते हैं, तो इसका मतलब आमतौर पर एक हार्डवेयर समस्या (या डिवाइस ड्राइवर समस्या, जो कर्नेल के समान दिखता है) होती है, जहां डिवाइस ड्राइवर हार्डवेयर के लिए कुछ करने की प्रतीक्षा कर रहा है जो कभी नहीं होगा। इसका मतलब यह भी हो सकता है कि आप NFS का उपयोग कर रहे हैं और NFS सर्वर डाउन हो रहा है (यह सर्वर के ठीक होने की प्रतीक्षा कर रहा है; आप समस्या से बचने के लिए "intr" विकल्प का भी उपयोग कर सकते हैं)।

अंत में, जिस कारण से आप पुनर्प्राप्त नहीं कर सकते हैं, वही कारण है कि कर्नेल प्रतीक्षा करता है जब तक कि उपयोगकर्ता मोड में सिग्नल देने या प्रक्रिया को मारने के लिए वापस नहीं आता है: यह संभवतः कर्नेल के डेटा संरचनाओं को भ्रष्ट करेगा (कोड एक व्यवधानपूर्ण नींद पर प्रतीक्षा कर रहा है जो एक त्रुटि प्राप्त कर सकता है जो इसे बताता है। उपयोगकर्ता स्थान पर लौटने के लिए, जहां प्रक्रिया को मार दिया जा सकता है, एक निर्बाध नींद पर इंतजार कर कोड किसी भी त्रुटि की उम्मीद नहीं है)।


1
फ़ाइलसिस्टम लॉकिंग बग भी एक संभावित कारण है, आईएमई।
टोबू

3
मुझे यह सब समझ नहीं आ रहा है। "आप अबाधित नींद से बच नहीं सकते हैं" - क्या ओएस को इस तरह से नहीं बनाया जा सकता है कि बिना सोए नींद केवल एक राज्य के रूप में नहीं होती है? फिर भ्रष्टाचार के बारे में हिस्सा - क्या प्रक्रिया का कर्नेल-मोड ही हिस्सा नहीं हो सकता है (या जो भी COULD भ्रष्टाचार का कारण बनता है) को समाप्त कर दिया जाए या बस इसके कोड को स्मृति में सही तरीके से संशोधित किया जाए? कृपया बताएं कि ऐसा करना इतना कठिन / असंभव क्यों है कि लिनक्स ने भी नहीं किया है। (मुझे लगा कि यह समस्या केवल विंडोज पर मौजूद है)
Dexter

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

@Dexter कर्नेल के बारे में सोचता है जैसे कि यह एक एकल बहु-थ्रेडेड प्रक्रिया थी, जहाँ प्रत्येक प्रक्रिया का कर्नेल-मोड हिस्सा कर्नेल के भीतर एक थ्रेड होता है। आपका सुझाव एक बहु-थ्रेडेड प्रोग्राम में किसी एक धागे को मारने जितना ही बुरा होगा: यह लटकते हुए ताले, डेटा संरचनाओं को अस्थायी रूप से संशोधित किया जा सकता है या संशोधित किया जा सकता है, और इसी तरह।
सीजरबी

@CesarB अच्छी तरह से आप एक धागे को मारने के बारे में सही हैं ... लेकिन "मुख्य" धागा नहीं हो सकता है (जो कि ओएस कर्नेल होगा और अन्य धागे उदाहरण के लिए ड्राइवर होंगे) किसी तरह इसे संभालते हैं? यद्यपि उन संरचनाओं को "संशोधित किए जाने के बीच में" लगता है कि यह वास्तव में एक कठिन मुद्दा है ... शायद हम वास्तव में कभी भी एक ओएस नहीं देखेंगे जहां निर्बाध प्रक्रियाएं असंभव होंगी :(
Dexter

23

एक पेज की गलती के बाद अबाधित प्रक्रियाएं USUALLY I / O की प्रतीक्षा कर रही हैं।

इस पर विचार करो:

  • थ्रेड एक ऐसे पृष्ठ पर पहुंचने का प्रयास करता है जो कोर में नहीं है (या तो एक निष्पादन योग्य है जो डिमांड-लोडेड है, अनाम मेमोरी का एक पेज जिसे स्वैप किया गया है, या एक एमएमएपी () डी फ़ाइल जो मांग भरी हुई है, जो बहुत अधिक हैं) वही चीज)
  • कर्नेल अब इसे लोड करने की कोशिश कर रहा है
  • पेज उपलब्ध होने तक प्रक्रिया जारी नहीं रह सकती।

इस अवस्था में प्रक्रिया / कार्य को बाधित नहीं किया जा सकता है, क्योंकि यह किसी भी सिग्नल को संभाल नहीं सकता है; यदि यह किया जाता है, तो एक और पृष्ठ दोष होता है और यह वापस वहीं होगा जहां यह था।

जब मैं "प्रक्रिया" कहता हूं, तो मेरा वास्तव में मतलब है "कार्य", जो कि लिनक्स (2.6) के तहत मोटे तौर पर "थ्रेड" में अनुवाद करता है, जिसमें / खरीद में व्यक्तिगत "थ्रेड ग्रुप" प्रविष्टि हो सकती है या नहीं हो सकती है।

कुछ मामलों में, यह लंबे समय तक इंतजार कर सकता है। इसका एक विशिष्ट उदाहरण वह स्थान होगा जहां निष्पादन योग्य या mmap'd फ़ाइल एक नेटवर्क फाइल सिस्टम पर होती है जहां सर्वर विफल हो गया है। यदि I / O अंततः सफल होता है, तो कार्य जारी रहेगा। यदि यह अंततः विफल हो जाता है, तो कार्य को आम तौर पर एक संकेत या कुछ और मिलेगा।


1
यदि यह अंततः विफल हो जाता है, तो कार्य को आम तौर पर एक संकेत या कुछ और मिलेगा। रुको, कर्नेल नहीं बनाया जा सकता है ताकि, जब उन "निर्बाध" प्रक्रियाओं को मार दिया जाए, तो यह केवल उन्हें I / I ऑपरेशन को विफल कर देता है? फिर प्रक्रिया उपयोगकर्ता मोड में वापस चली जाएगी और चली जाएगी? उन 'डी' राज्य प्रक्रियाओं को सुरक्षित रूप से मारने का एक तरीका है। मुझे लगता है कि यह आसान नहीं है और यही कारण है कि न तो विंडोज या लिनक्स के पास अभी तक इसकी संभावना है। दूसरी तरफ, मैं उन प्रक्रियाओं को कम से कम अनिश्चित रूप से मारने में सक्षम होना चाहता हूं। मैं संभावित सिस्टम क्रैश या जो भी हो उसकी परवाह नहीं करता ...
Dexter

@Dexter हम्म, मैंने विंडोज के साथ इस समस्या का कभी अनुभव नहीं किया है। वहाँ इसे पुन: पेश करने का एक तरीका क्या है? कम से कम इस पोस्ट के अनुसार , विंडोज में सभी I / O अनुरोध बाधित हो सकते हैं।
रुस्लान

1

आपके तीसरे प्रश्न के लिए: मुझे लगता है कि आप बिना रुके प्रक्रिया को मार सकते हैं sudo kill -HUP 1। यह चल रही प्रक्रियाओं को समाप्त किए बिना init को पुनः आरंभ करेगा और इसे चलाने के बाद, मेरी निर्बाध प्रक्रियाएं समाप्त हो गईं।


-3

यदि आप "ज़ोंबी" प्रक्रिया के बारे में बात कर रहे हैं (जिसे पीएस आउटपुट में "ज़ोंबी" के रूप में नामित किया गया है), तो यह प्रक्रिया सूची में एक हानिरहित रिकॉर्ड है जो किसी को अपने रिटर्न कोड को इकट्ठा करने के लिए इंतजार कर रहा है और इसे सुरक्षित रूप से अनदेखा किया जा सकता है।

क्या आप बता सकते हैं कि आपके लिए क्या और "निर्बाध प्रक्रिया" है? क्या यह "किल -9" और खुशी से चग्स के साथ बच जाता है? यदि ऐसा है, तो यह कुछ syscall पर अटका हुआ है, जो कुछ ड्राइवर में अटका हुआ है, और आप रिबूट तक इस प्रक्रिया के साथ अटके हुए हैं (और कभी-कभी जल्द ही रिबूट करना बेहतर होता है) या संबंधित ड्राइवर को अनलोड करना (जो होने की संभावना नहीं है) । आप यह जानने के लिए "स्ट्रेस" का उपयोग करने की कोशिश कर सकते हैं कि आपकी प्रक्रिया कहाँ अटक गई है और भविष्य में इससे बचें।


नहीं ड्राइवरों किया जा सकता है जबरदस्ती उसी तरह एक प्रक्रिया मार कर उतार दिया? मुझे पता है कि कर्नेल मोड में उपयोगकर्ता मोड की तुलना में अधिक विशेषाधिकार प्राप्त है, लेकिन यह कभी भी अधिक विशेषाधिकार प्राप्त नहीं हो सकता है कि ऑपरेटिंग सिस्टम। कर्नेल मोड में निष्पादित कुछ भी हमेशा कर्नेल मोड में निष्पादित किसी और चीज के साथ छेड़छाड़ कर सकता है - बस कोई नियंत्रण नहीं है।
डेक्सटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.