लिनक्स प्रोसेस स्टेट्स


90

लिनक्स में, डिस्क से ब्लॉक पढ़ने की आवश्यकता होने पर एक प्रक्रिया की स्थिति क्या होती है? क्या यह अवरुद्ध है? यदि हां, तो निष्पादित करने के लिए एक और प्रक्रिया कैसे चुनी जाती है?

जवाबों:


87

फ़ाइल डिस्क्रिप्टर रिटर्न से read()या उसके लिए प्रतीक्षा करते समय write(), प्रक्रिया को एक विशेष प्रकार की नींद में रखा जाएगा, जिसे "डी" या "डिस्क स्लीप" के रूप में जाना जाता है। यह विशेष है, क्योंकि इस तरह की स्थिति में प्रक्रिया को मारा या बाधित नहीं किया जा सकता है। Ioctl () से वापसी की प्रतीक्षा करने वाली एक प्रक्रिया को भी इस तरीके से सोने के लिए रखा जाएगा।

इसका अपवाद तब होता है जब कोई फ़ाइल (जैसे कि टर्मिनल या अन्य वर्ण डिवाइस) O_NONBLOCKमोड में खोली जाती है, तब पारित की जाती है जब यह मान लिया जाता है कि एक डिवाइस (जैसे मॉडेम) को आरंभ करने के लिए समय की आवश्यकता होगी। हालाँकि, आपने अपने प्रश्न में ब्लॉक उपकरणों का संकेत दिया है। इसके अलावा, मैंने कभी कोशिश नहीं की है ioctl()कि गैर ब्लॉकिंग मोड में खोले गए fd पर ब्लॉक होने की संभावना है (कम से कम जानबूझकर नहीं)।

किसी अन्य प्रक्रिया को कैसे चुना जाता है यह पूरी तरह से उस शेड्यूलर पर निर्भर करता है जिसका आप उपयोग कर रहे हैं, साथ ही साथ इस शेड्यूलर के भीतर उनके वज़न को संशोधित करने के लिए अन्य प्रक्रियाओं ने क्या किया है।

कुछ परिस्थितियों में कुछ उपयोगकर्ता अंतरिक्ष कार्यक्रम रिबूट होने तक हमेशा के लिए इस स्थिति में बने रहने के लिए जाने जाते हैं। ये आम तौर पर अन्य "लाश" के साथ समूहीकृत होते हैं, लेकिन यह शब्द सही नहीं होगा क्योंकि वे तकनीकी रूप से खराब नहीं हैं।


1
"Ioctl () से वापसी की प्रतीक्षा करने वाली एक प्रक्रिया को भी इस तरीके से सोने के लिए रखा जाएगा"। मैंने सिर्फ एक ब्लॉकिंग IOCTL पर प्रतीक्षा कर रहे अपने यूजरस्पेस प्रोसेस को मार दिया है, इसलिए यह सच नहीं है। जब तक मैं
गलत समझ

इस तरह के टेस्ट के लिए समय निकालना काफी मुश्किल होगा । निर्बाध प्रक्रियाओं को नहीं मारा जा सकता है; यदि आप इसे मारने में सक्षम थे, तो यह बस अवरुद्ध कर रहा था (कर्नेल ioctl के किसी भी हिस्से के बीच में नहीं था, और आपके द्वारा पारित स्थान पर उपयोगकर्ता स्थान पर किसी भी इसी प्रतिक्रिया की नकल की (या कम से कम नहीं थी) नकल के बीच))। जब यह लिखा गया था तब से लिनक्स 2009 में भी बहुत बदल गया है; घटना बहुत कम देखने योग्य है क्योंकि यह एक बार थी।
टिम पोस्ट

133

जब एक प्रक्रिया को डिस्क से डेटा प्राप्त करने की आवश्यकता होती है, तो यह सीपीयू पर प्रभावी ढंग से बंद हो जाता है ताकि अन्य प्रक्रियाएं चल सकें क्योंकि ऑपरेशन को पूरा होने में लंबा समय लग सकता है - डिस्क के लिए कम से कम 5ms का समय सामान्य है, और 5ms 10 मिलियन है सीपीयू चक्र, कार्यक्रम के दृष्टिकोण से एक अनंत काल!

प्रोग्रामर के दृष्टिकोण से ("यूजर्सस्पेस में" भी कहा गया है), इसे ब्लॉकिंग सिस्टम कॉल कहा जाता है । यदि आप कॉल करते हैं write(2)(जो एक ही नाम के सिस्टम कॉल के चारों ओर एक पतली libc आवरण है), तो आपकी प्रक्रिया उस सीमा पर बिल्कुल नहीं रुकती है; यह जारी है, कर्नेल में, सिस्टम कॉल कोड चला रहा है। अधिकांश समय यह एक विशिष्ट डिस्क नियंत्रक चालक (फ़ाइल नाम → फाइलसिस्टम / वीएफएस → ब्लॉक डिवाइस → डिवाइस ड्राइवर) तक जाता है, जहां डिस्क पर एक ब्लॉक लाने के लिए एक आदेश उचित हार्डवेयर को प्रस्तुत किया जाता है, जो बहुत ही महत्वपूर्ण है। तेजी से ऑपरेशन ज्यादातर समय।

जब इस प्रक्रिया को स्लीप अवस्था में रखा जाता है (कर्नेल स्पेस में, ब्लॉकिंग को स्लीपिंग कहा जाता है - कर्नेल बिंदु से कुछ भी 'अवरुद्ध' कभी नहीं होता)। एक बार जब हार्डवेयर ने उचित डेटा प्राप्त कर लिया है, तो यह जागृत हो जाएगा, फिर प्रक्रिया को चलाने योग्य के रूप में चिह्नित किया जाएगा और शेड्यूल किया जाएगा। आखिरकार, शेड्यूलर प्रक्रिया को चलाएगा।

अंत में, यूजरस्पेस में, अवरुद्ध प्रणाली उचित स्थिति और डेटा के साथ रिटर्न कॉल करती है, और प्रोग्राम फ्लो चलता है।

गैर-अवरोधक मोड (देखें और ) O_NONBLOCKमें अधिकांश I / O सिस्टम कॉल को लागू करना संभव है । इस स्थिति में, सिस्टम कॉल तुरंत वापस आती है और केवल डिस्क ऑपरेशन सबमिट करने की रिपोर्ट करती है। प्रोग्रामर को बाद में स्पष्ट रूप से जांचना होगा कि क्या ऑपरेशन पूरा हुआ, सफलतापूर्वक या नहीं, और इसका परिणाम प्राप्त करना (जैसे, साथ )। इसे एसिंक्रोनस या ईवेंट-आधारित प्रोग्रामिंग कहा जाता है।open(2)fcntl(2)select(2)

डी राज्य (जिसे TASK_UNINTERRUPTIBLEलिनक्स राज्य नामों में कहा जाता है) का उल्लेख करने वाले अधिकांश उत्तर गलत हैं। डी राज्य एक विशेष स्लीप मोड जो केवल एक कर्नेल अंतरिक्ष कोड पथ, जब कि कोड पथ में शुरू हो रहा है है बाधित नहीं किया जा सकता है (क्योंकि यह कार्यक्रम करने के लिए बहुत जटिल हो जाएगा), उम्मीद के साथ कि यह केवल एक बहुत ही के लिए ब्लॉक कर देगा कम समय। मेरा मानना ​​है कि अधिकांश "डी स्टेट्स" वास्तव में अदृश्य हैं; वे बहुत कम रहते हैं और 'टॉप' जैसे सैंपलिंग टूल्स द्वारा नहीं देखे जा सकते हैं।

आप कुछ स्थितियों में डी राज्य में अनजानी प्रक्रियाओं का सामना कर सकते हैं। एनएफएस उस के लिए प्रसिद्ध है, और मैंने इसे कई बार सामना किया है। मुझे लगता है कि कुछ वीएफएस कोड रास्तों के बीच एक शब्दार्थ झड़प है, जो हमेशा स्थानीय डिस्क और तेजी से त्रुटि का पता लगाने के लिए मानती है (एसएटीए पर, एक त्रुटि टाइमआउट लगभग 100 एमएस होगा), और एनएफएस, जो वास्तव में नेटवर्क से डेटा प्राप्त करता है जो अधिक लचीला है और इसमें धीमी गति से रिकवरी है (300 सेकंड का एक टीसीपी समय सामान्य है)। राज्य में लिनक्स 2.6.25 में पेश किए गए शांत समाधान के लिए इस लेख को पढ़ें TASK_KILLABLE। इस युग से पहले एक हैक था जहाँ आप वास्तव में एनजीएस प्रोसेस क्लाइंट्स को एक संकेत भेज सकते हैं एक कर्नेल को कर्नेल थ्रेड पर भेजकर rpciod, लेकिन उस बदसूरत चाल के बारे में भूल जाएं।…


2
विस्तृत प्रतिक्रिया के लिए +1, लेकिन कृपया ध्यान दें कि इस धागे का लगभग दो वर्षों से स्वीकृत उत्तर है। यदि आप अधिक हाल के प्रश्नों पर हाथ उधार देना चाहते हैं, तो "प्रश्न" लिंक को हिट करें। ढेर अतिप्रवाह में आपका स्वागत है, और योगदान देने के लिए धन्यवाद!
गर्गानुचेट

20
यह उत्तर एनएफएस का उल्लेख करने वाला एकमात्र है, जो कुछ वातावरणों में डी राज्य में प्रक्रियाओं के लिए सबसे आम स्पष्टीकरण है। +1।
Pinko

14
बहुत अच्छा जवाब, धन्यवाद। यह भी ध्यान दें कि जिस प्रक्रिया को स्वैप किए गए पृष्ठों की प्रतीक्षा करते हुए डी स्थिति में जाते हैं, इसलिए डी थ्रेशिंग प्रक्रिया लंबे समय तक डी राज्य में होगी।
cha0site

@zerodeux अच्छा जवाब है, लेकिन मुझे लगता है कि आपका स्कीमा (फ़ाइल नाम -> फ़ाइल सिस्टम / VFS -> ब्लॉक डिवाइस -> डिवाइस ड्राइवर) यह होना चाहिए (फ़ाइल नाम -> VFS -> फाइलसिस्टम (ext3) -> ब्लॉक डिवाइस -> डिवाइस ड्राइवर)
c4f4t0r

1
क्या यह मान लेना सुरक्षित होगा कि स्पिन के इंतजार में कर्नेल में बिताया गया समय (जो डिस्क i / o से संबंधित हो सकता है या नहीं) सभी को डी-स्टेट के रूप में रिपोर्ट किया गया /proc/stat?
wick

8

I / O करने वाली एक प्रक्रिया को D अवस्था (निर्बाध नींद) में रखा जाएगा , जो CPU को तब तक मुक्त करता है जब तक कि कोई हार्डवेयर व्यवधान न हो जो CPU को प्रोग्राम को निष्पादित करने के लिए वापस जाने के लिए कहता है। man psअन्य प्रक्रिया राज्यों के लिए देखें ।

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

में 2.6 गिरी , वहाँ एक है हे (1) समय जटिलता अनुसूचक कितने प्रक्रियाओं द्वारा चलाए ऊपर है, यह लगातार समय में सीपीयू आवंटित करेगा, तो कोई बात नहीं। यह अधिक जटिल है, हालांकि 2.6 के बाद से प्रीमेशन और सीपीयू लोड बैलेंसिंग एक आसान एल्गोरिथ्म नहीं है। किसी भी मामले में, यह कुशल है और सीपीयू निष्क्रिय नहीं रहेगा, जब तक आप आई / ओ की प्रतीक्षा नहीं करते।


3

जैसा कि पहले से ही दूसरों द्वारा समझाया गया है, "डी" राज्य (निर्बाध नींद) में प्रक्रियाएं पीएस प्रक्रिया के लटकने के लिए जिम्मेदार हैं। मेरे लिए यह रेडहैट 6.x और ऑटोमैटिक एनएफएस होम डाइरेक्टरीज़ के साथ कई बार हुआ है।

डी राज्य में प्रक्रियाओं को सूचीबद्ध करने के लिए आप निम्नलिखित आदेशों का उपयोग कर सकते हैं:

cd /proc
for i in [0-9]*;do echo -n "$i :";cat $i/status |grep ^State;done|grep D

प्रक्रिया की वर्तमान निर्देशिका को जानने के लिए और, हो सकता है कि माउंट की गई NFS डिस्क में आपके द्वारा निम्न उदाहरण के समान एक कमांड का उपयोग किया जा सकता है (31134 को स्लीपिंग प्रक्रिया संख्या के साथ बदलें):

# ls -l /proc/31134/cwd
lrwxrwxrwx 1 pippo users 0 Aug  2 16:25 /proc/31134/cwd -> /auto/pippo

मैंने पाया कि संबंधित माउंट किए गए nfs फाइल सिस्टम में -f (बल) स्विच के साथ umount कमांड देना, नींद की प्रक्रिया को जगाने में सक्षम था:

umount -f /auto/pippo

फ़ाइल सिस्टम अनमाउंट नहीं था, क्योंकि यह व्यस्त था, लेकिन संबंधित प्रक्रिया जाग गई और मैं रिबूट किए बिना समस्या को हल करने में सक्षम था।


1

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

वे प्रक्रियाएँ जो I / O के पूरा होने की प्रतीक्षा कर रही हैं, आमतौर पर राज्य में डी, जैसे, psऔरtop


मैंने कुल मेमोरी के लगभग 10% का उपयोग करके कई प्रक्रिया शुरू की। मैंने देखा कि उनमें से कई डी राज्य में हैं। क्या यह इस विशेष मशीन पर धीमी गति से IO के कारण है? कहो कि मेरे पास 9 प्रक्रियाएं हैं, वे IO के लिए प्रतिस्पर्धा कर सकते हैं और उनमें से कई डी राज्य में हैं।
केमिन झोउ

@KeminZhou सीपीयू की गति की तुलना में, I / O बहुत धीमा है - यहां तक ​​कि तेजी से I / O। एक एकल I / O भारी प्रक्रिया एक चुंबकीय डिस्क को आसानी से व्यस्त कर सकती है, यहां तक ​​कि एसएसडी भी। 10 I / O भारी प्रक्रियाएं काफी व्यस्त हो सकती हैं।
जुरा

1

हां, रीड () सिस्टम कॉल में कार्य अवरुद्ध हो जाता है। एक अन्य कार्य जो तैयार रन है, या यदि कोई अन्य कार्य तैयार नहीं है, तो निष्क्रिय कार्य (सीपीयू के लिए) चलता है।

एक सामान्य, ब्लॉकिंग डिस्क रीड "D" स्थिति में प्रवेश करने का कारण बनता है (जैसा कि अन्य ने नोट किया है)। ऐसे कार्य लोड औसत में योगदान करते हैं, भले ही वे सीपीयू का उपभोग नहीं कर रहे हों।

कुछ अन्य प्रकार के IO, विशेष रूप से टैटी और नेटवर्क, एक समान व्यवहार नहीं करते हैं - प्रक्रिया "S" स्थिति में समाप्त हो जाती है और बाधित हो सकती है और लोड औसत के खिलाफ गिनती नहीं करती है।



0

आमतौर पर प्रक्रिया अवरुद्ध हो जाएगी। यदि रीड ऑपरेशन नॉन-ब्लॉकिंग के रूप में चिह्नित फ़ाइल डिस्क्रिप्टर पर है या यदि प्रक्रिया अतुल्यकालिक IO का उपयोग कर रही है तो यह ब्लॉक नहीं होगी। इसके अलावा अगर प्रक्रिया में अन्य धागे हैं जो अवरुद्ध नहीं हैं तो वे चालू रह सकते हैं।

निर्णय के रूप में जो प्रक्रिया आगे चलती है कर्नेल में शेड्यूलर पर निर्भर है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.