बहु-थ्रेडेड एप्लिकेशन लिखते समय, अनुभवी सबसे आम समस्याओं में से एक गतिरोध हैं।
समुदाय के लिए मेरे प्रश्न हैं:
गतिरोध क्या है?
आप उनका पता कैसे लगाते हैं?
क्या आप उन्हें संभालते हैं?
और अंत में, आप उन्हें होने से कैसे रोकेंगे?
बहु-थ्रेडेड एप्लिकेशन लिखते समय, अनुभवी सबसे आम समस्याओं में से एक गतिरोध हैं।
समुदाय के लिए मेरे प्रश्न हैं:
गतिरोध क्या है?
आप उनका पता कैसे लगाते हैं?
क्या आप उन्हें संभालते हैं?
और अंत में, आप उन्हें होने से कैसे रोकेंगे?
जवाबों:
एक लॉक तब होता है जब एक ही समय में कई प्रोसेस एक ही रिसोर्स को एक्सेस करने की कोशिश करते हैं।
एक प्रक्रिया खत्म हो जाती है और दूसरे के खत्म होने का इंतजार करना चाहिए।
एक गतिरोध तब होता है जब प्रतीक्षा प्रक्रिया अभी भी किसी अन्य संसाधन को पकड़े रहती है जिसे समाप्त करने से पहले पहली आवश्यकता होती है।
तो, एक उदाहरण:
संसाधन A और संसाधन B का उपयोग प्रक्रिया X और प्रक्रिया Y द्वारा किया जाता है
गतिरोध से बचने का सबसे अच्छा तरीका इस तरह से प्रक्रियाओं को पार करने से बचना है। जितना हो सके उतना कुछ भी लॉक करने की आवश्यकता को कम करें।
डेटाबेस में एक ही लेन-देन में विभिन्न तालिकाओं में बहुत सारे बदलाव करने से बचें, जितना संभव हो उतना आशावादी / गंदे / नोलॉक रीडर्स के लिए ट्रिगर और स्विच से बचें।
मुझे अपराध की फिल्मों से गतिरोध की स्थिति के लिए एक वास्तविक दुनिया (वास्तव में वास्तविक नहीं) उदाहरण की व्याख्या करें। कल्पना कीजिए कि एक अपराधी एक बंधक रखता है और उसके खिलाफ, एक पुलिस भी एक बंधक रखता है जो अपराधी का दोस्त है। इस मामले में, अपराधी बंधक को जाने नहीं दे रहा है अगर पुलिस अपने दोस्त को जाने नहीं देगी। साथ ही पुलिस अपराधी के दोस्त को जाने नहीं दे रही है, जब तक कि अपराधी को बंधक मुक्त नहीं किया जाता है। यह एक अंतहीन अविश्वसनीय स्थिति है, क्योंकि दोनों पक्ष एक दूसरे से पहले कदम पर जोर दे रहे हैं।
तो बस, जब दो थ्रेड्स को दो अलग-अलग संसाधनों की आवश्यकता होती है और उनमें से प्रत्येक के पास संसाधन का लॉक होता है जो अन्य की आवश्यकता होती है, यह एक गतिरोध है।
आप एक लड़की के साथ डेटिंग कर रहे हैं और एक तर्क के एक दिन बाद, दोनों पक्ष एक-दूसरे के लिए दिल तोड़ चुके हैं और आई- ए -सॉरी-एंड-आई-मिस-यू कॉल की प्रतीक्षा कर रहे हैं। इस स्थिति में, दोनों पक्ष एक दूसरे से संवाद करना चाहते हैं यदि और केवल तभी उनमें से एक दूसरे से आई -एम-सॉरी कॉल प्राप्त करता है। चूँकि प्रत्येक न तो संचार शुरू करने जा रहा है और एक निष्क्रिय स्थिति में प्रतीक्षा कर रहा है, दोनों संचार शुरू करने के लिए एक दूसरे की प्रतीक्षा करेंगे जो एक गतिरोध की स्थिति में समाप्त होता है।
गतिरोध केवल तब होगा जब आपके पास दो या अधिक ताले हों जो एक ही समय में जलीय हो सकते हैं और उन्हें अलग-अलग क्रम में पकड़ा जाता है।
गतिरोध से बचने के तरीके हैं:
गतिरोध को परिभाषित करने के लिए, पहले मैं प्रक्रिया को परिभाषित करूंगा।
प्रक्रिया : जैसा कि हम जानते हैं कि प्रक्रिया program
निष्पादन में कुछ भी नहीं है ।
संसाधन : प्रोग्राम प्रक्रिया को निष्पादित करने के लिए कुछ संसाधनों की आवश्यकता होती है। संसाधन श्रेणियों में मेमोरी, प्रिंटर, सीपीयू, खुली फाइलें, टेप ड्राइव, सीडी-रोम, आदि शामिल हो सकते हैं।
डेडलॉक : डेडलॉक एक ऐसी स्थिति या स्थिति होती है जब दो या दो से अधिक प्रक्रियाएं कुछ संसाधनों को पकड़ कर कुछ और संसाधनों को प्राप्त करने की कोशिश कर रही होती हैं, और वे संसाधनों को तब तक जारी नहीं कर सकते हैं जब तक कि वे निष्पादन को समाप्त नहीं कर देते।
गतिरोध की स्थिति या स्थिति
उपरोक्त आरेख में दो प्रक्रिया P1 और P2 हैं और दो संसाधन R1 और R2 हैं ।
संसाधन R1 को P1 को संसाधित करने के लिए आवंटित किया गया है और संसाधन R2 को P2 को संसाधित करने के लिए आवंटित किया गया है । प्रक्रिया के पूर्ण निष्पादन के लिए P1 को संसाधन R2 की आवश्यकता होती है , इसलिए R2 के लिए P1 अनुरोध , लेकिन R2 पहले से ही P2 को आवंटित किया जाता है ।
उसी तरह प्रोसेस पी 2 को अपने निष्पादन को पूरा करने के लिए आर 1 की जरूरत है , लेकिन आर 1 पहले से ही पी 1 को आवंटित किया गया है ।
दोनों प्रक्रियाएं अपने संसाधन को तब तक जारी नहीं कर सकती हैं जब तक कि वे अपने निष्पादन को पूरा नहीं करते हैं। इसलिए दोनों दूसरे संसाधनों का इंतजार कर रहे हैं और वे हमेशा के लिए इंतजार करेंगे। तो यह एक DEADLOCK कंडीशन है।
गतिरोध उत्पन्न होने के लिए, चार शर्तें सही होनी चाहिए।
और ये सभी हालत ऊपर आरेख में संतुष्ट हैं।
एक गतिरोध तब होता है जब एक धागा ऐसी चीज़ के लिए इंतजार कर रहा है जो कभी नहीं होता है।
आमतौर पर, यह तब होता है जब एक धागा म्यूटेक्स या सेमाफोर पर इंतजार कर रहा होता है जो पिछले मालिक द्वारा कभी जारी नहीं किया गया था।
यह भी अक्सर होता है जब आपके पास दो धागे और दो ताले जैसी स्थिति होती है:
Thread 1 Thread 2
Lock1->Lock(); Lock2->Lock();
WaitForLock2(); WaitForLock1(); <-- Oops!
आप आम तौर पर उनका पता लगाते हैं क्योंकि ऐसी चीजें जो आप होने की उम्मीद करते हैं, कभी नहीं करते हैं, या एप्लिकेशन पूरी तरह से लटका हुआ है।
आप डेडलॉक के तहत इस अद्भुत लेख पर एक नज़र डाल सकते हैं । यह C # में है, लेकिन विचार अभी भी अन्य प्लेटफॉर्म के लिए समान है। मैं यहाँ आसान पढ़ने के लिए बोली
एक गतिरोध तब होता है जब दो सूत्र एक दूसरे द्वारा रखे गए संसाधन की प्रतीक्षा करते हैं, इसलिए न तो आगे बढ़ सकते हैं। इसका वर्णन करने का सबसे आसान तरीका दो तालों के साथ है:
object locker1 = new object();
object locker2 = new object();
new Thread (() => {
lock (locker1)
{
Thread.Sleep (1000);
lock (locker2); // Deadlock
}
}).Start();
lock (locker2)
{
Thread.Sleep (1000);
lock (locker1); // Deadlock
}
OS में मल्टीप्रोसेसिंग / मल्टीप्रोग्रामिंग समस्याओं में डेडलॉक एक आम समस्या है। कहते हैं कि दो प्रक्रियाएँ P1, P2 और दो विश्व स्तर पर साझा करने योग्य संसाधन R1, R2 हैं और महत्वपूर्ण सेक्शन में दोनों संसाधनों को एक्सेस करने की आवश्यकता है
प्रारंभ में, OS P1 और R2 को P2 प्रोसेस करने के लिए R1 असाइन करता है। जैसा कि दोनों प्रक्रियाएं समवर्ती रूप से चल रही हैं, वे अपने कोड को निष्पादित करना शुरू कर सकते हैं, लेकिन जब कोई प्रक्रिया महत्वपूर्ण खंड को हिट करती है, तो समस्या उत्पन्न होती है। तो प्रक्रिया R1 R2 और इसके विपरीत रिलीज करने के लिए प्रक्रिया P2 की प्रतीक्षा करेगी ... इसलिए वे हमेशा के लिए प्रतीक्षा करेंगे (DEADLOCK CONDITT)।
एक छोटा सा जवाब ...
आपकी माँ (OS),
आप (P1),
आपका भाई (P2),
Apple (R1),
चाकू (R2),
क्रिटिकल सेक्शन (चाकू से सेब काटना)।आपकी माँ आपको शुरुआत में अपने भाई को सेब और चाकू देती है।
दोनों खुश हैं और खेल रहे हैं (उनके कोड निष्पादित)।
आप में से कोई भी किसी समय पर सेब (क्रिटिकल सेक्शन) को काटना चाहता है।
आप अपने भाई को सेब नहीं देना चाहते।
आपका भाई आपको चाकू नहीं देना चाहता।
तो आप दोनों एक बहुत लंबे समय के लिए इंतजार करने जा रहे हैं :)
गतिरोध तब होता है जब दो धागे एक्वायर लॉक होते हैं जो उनमें से किसी को भी प्रगति करने से रोकते हैं। उनसे बचने का सबसे अच्छा तरीका सावधानीपूर्वक विकास है। कई एम्बेडेड सिस्टम वॉचडॉग टाइमर (एक टाइमर जो सिस्टम को रीसेट करता है जब भी यह निश्चित अवधि के लिए लटका होता है) का उपयोग करके उनके खिलाफ सुरक्षा करता है।
एक गतिरोध तब होता है जब थ्रेड्स या प्रक्रियाओं की एक गोलाकार श्रृंखला होती है जो प्रत्येक एक बंद संसाधन को पकड़ते हैं और श्रृंखला में अगले तत्व द्वारा रखे गए संसाधन को लॉक करने का प्रयास कर रहे हैं। उदाहरण के लिए, दो धागे जो क्रमशः ए और लॉक बी को लॉक करते हैं, और दोनों दूसरे लॉक को प्राप्त करने की कोशिश कर रहे हैं।
डेडलॉक स्थिति को समझने के लिए एक क्लासिक और बहुत ही सरल कार्यक्रम : -
public class Lazy {
private static boolean initialized = false;
static {
Thread t = new Thread(new Runnable() {
public void run() {
initialized = true;
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println(initialized);
}
}
जब मुख्य सूत्र लेज़ी.मैन को आमंत्रित करता है, तो यह जाँचता है कि क्या क्लास लेज़ी को इनिशियलाइज़ किया गया है और क्लास को इनिशियलाइज़ करना शुरू करता है। मुख्य थ्रेड अब झूठे के लिए इनिशियलाइज़ सेट करता है, एक बैकग्राउंड थ्रेड बनाता है और शुरू करता है जिसकी रन मेथड सच से इनिशियलाइज़ होती है, और बैकग्राउंड थ्रेड के पूरा होने का इंतज़ार करता है।
इस समय, क्लास को वर्तमान में एक और थ्रेड द्वारा प्रारंभ किया जा रहा है। इन परिस्थितियों में, वर्तमान थ्रेड, जो बैकग्राउंड थ्रेड है, वर्ग ऑब्जेक्ट पर प्रारंभ होने तक प्रतीक्षा करता है। दुर्भाग्य से, जो धागा इनिशियलाइज़ेशन कर रहा है, मुख्य धागा, बैकग्राउंड थ्रेड के पूरा होने की प्रतीक्षा कर रहा है। क्योंकि दोनों थ्रेड्स अब एक दूसरे की प्रतीक्षा कर रहे हैं, प्रोग्राम डीएडलॉक्ड है।
गतिरोध एक ऐसी प्रणाली की स्थिति है जिसमें कोई भी प्रक्रिया / धागा किसी कार्रवाई को अंजाम देने में सक्षम नहीं होता है। जैसा कि दूसरों ने उल्लेख किया है, एक गतिरोध आमतौर पर एक ऐसी स्थिति का परिणाम होता है, जहां प्रत्येक प्रक्रिया / थ्रेड एक ऐसे संसाधन को लॉक करने की इच्छा रखता है जो पहले से ही दूसरे (या यहां तक कि समान) प्रक्रिया / थ्रेड द्वारा लॉक हो।
उन्हें खोजने और उनसे बचने के लिए विभिन्न तरीके हैं। एक बहुत सोच रहा है और / या बहुत सारी चीजों की कोशिश कर रहा है। हालांकि, समानता से निपटना बेहद मुश्किल है और अधिकांश (यदि सभी नहीं) तो लोग पूरी तरह से समस्याओं से बच नहीं पाएंगे।
यदि आप इस प्रकार के मुद्दों से निपटने के लिए गंभीर हैं तो कुछ और औपचारिक तरीके उपयोगी हो सकते हैं। सबसे व्यावहारिक तरीका जो मुझे पता है वह प्रक्रिया सिद्धांत दृष्टिकोण का उपयोग करना है। यहां आप अपने सिस्टम को कुछ प्रोसेस लैंग्वेज (जैसे CCS, CSP, ACP, mCRL2, LOTOS) में मॉडल करते हैं और डेडलॉक (और शायद कुछ अन्य गुणों के साथ) के लिए उपलब्ध टूल (मॉडल-) की जांच करते हैं। टूलसेट के उपयोग के उदाहरण एफडीआर, एमसीआरएल 2, सीएडीपी और उप्पल हैं। कुछ बहादुर आत्माएँ विशुद्ध रूप से प्रतीकात्मक तरीकों (प्रमेय सिद्ध करना; ओविकी-ग्रिज़ की तलाश) का उपयोग करके अपने सिस्टम को गतिरोध मुक्त साबित कर सकती हैं।
हालांकि, इन औपचारिक तरीकों को आमतौर पर कुछ प्रयास करने की आवश्यकता होती है (जैसे प्रक्रिया सिद्धांत की मूल बातें सीखना)। लेकिन मुझे लगता है कि यह इस तथ्य का परिणाम है कि ये समस्याएं कठिन हैं।
गतिरोध एक ऐसी स्थिति होती है जब उपलब्ध संसाधनों की कम संख्या होती है क्योंकि यह विभिन्न प्रक्रिया द्वारा अनुरोध किया जाता है। इसका मतलब है कि जब उपलब्ध संसाधनों की संख्या उपयोगकर्ता द्वारा अनुरोध किए जाने से कम हो जाती है तो उस समय यह प्रक्रिया प्रतीक्षा की स्थिति में चली जाती है। कुछ समय के लिए प्रतीक्षा अधिक बढ़ जाती है और तब संसाधनों की कमी की समस्या की जांच करने का कोई मौका नहीं होता है। इस स्थिति को गतिरोध के रूप में जाना जाता है। दरअसल, गतिरोध हमारे लिए एक बड़ी समस्या है और यह केवल मल्टीटास्किंग ऑपरेटिंग सिस्टम में होता है। डेडलॉक सिंगल टास्किंग ऑपरेटिंग सिस्टम में नहीं हो सकता है क्योंकि सभी संसाधन केवल उस कार्य के लिए मौजूद हैं जो वर्तमान में चल रहा है ......
ऊपर कुछ स्पष्टीकरण अच्छे हैं। आशा है कि यह भी उपयोगी हो सकता है: https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html
एक डेटाबेस में, जब एक सत्र (जैसे ora) दूसरे सत्र (उदाहरण डेटा) द्वारा आयोजित संसाधन चाहता है, लेकिन वह सत्र (डेटा) भी एक संसाधन चाहता है जो पहले सत्र (ora) द्वारा आयोजित किया जाता है। इसमें 2 से अधिक सत्र भी शामिल हो सकते हैं, लेकिन विचार समान होगा। दरअसल, डेडलॉक कुछ लेनदेन को काम करने से रोकता है। उदाहरण के लिए: मान लीजिए, ORA-DATA लॉक A और अनुरोध B और SKU लॉक B रखता है और लॉक A का अनुरोध करता है।
धन्यवाद,
गतिरोध तब होता है जब एक धागा समाप्त होने के लिए दूसरे धागे की प्रतीक्षा कर रहा है और इसके विपरीत।
कैसे बचें?
- नेस्टेड लॉक से
बचें - अनावश्यक लॉक से बचें
- थ्रेड ज्वाइन का उपयोग करें ()
आप इसका पता कैसे लगाते हैं?
इस कमांड को cmd में चलाएं:
jcmd $PID Thread.print
संदर्भ : geeksforgeeks
गतिरोध केवल तालों के साथ नहीं होता है, हालांकि यह सबसे लगातार कारण है। C ++ में, आप दो थ्रेड्स के साथ गतिरोध बना सकते हैं और प्रत्येक थ्रेड कॉल ज्वाइन होने से कोई लॉक नहीं है (दूसरे पर) :: थ्रेड ऑब्जेक्ट।
साझा संसाधनों तक पहुंच को नियंत्रित करने के लिए लॉकिंग का उपयोग गतिरोध से ग्रस्त है, और लेन-देन अनुसूचक अकेले उनकी घटनाओं को रोक नहीं सकता है।
उदाहरण के लिए, रिलेशनल डेटाबेस सिस्टम ट्रांजैक्शन एसीआईडी प्रॉपर्टी की गारंटी के लिए विभिन्न तालों का उपयोग करते हैं ।
कोई फर्क नहीं पड़ता कि आप किस रिलेशनल डेटाबेस सिस्टम का उपयोग कर रहे हैं, हमेशा एक निश्चित टेबल रिकॉर्ड को संशोधित करते समय ताले को अधिग्रहित किया जाएगा (जैसे, UPDATE
या DELETE
)। वर्तमान में चल रहे लेन-देन द्वारा संशोधित की गई एक पंक्ति को लॉक किए बिना, एटॉमिसिटी से समझौता किया जाएगा ।
जैसा कि मैंने इस लेख में बताया है , एक गतिरोध तब होता है जब दो समवर्ती लेनदेन प्रगति नहीं कर सकते क्योंकि प्रत्येक एक लॉक जारी करने के लिए दूसरे की प्रतीक्षा करता है, जैसा कि निम्नलिखित चित्र में दिखाया गया है।
क्योंकि दोनों लेन-देन लॉक अधिग्रहण के चरण में हैं, न ही कोई अगले को प्राप्त करने से पहले एक लॉक जारी करता है।
यदि आप कॉनकॉरैन्सी कंट्रोल एल्गोरिदम का उपयोग कर रहे हैं जो तालों पर निर्भर है, तो गतिरोध की स्थिति में चलने का जोखिम हमेशा रहता है। गतिरोध किसी भी डेटाबेस वातावरण में हो सकता है, न कि केवल डेटाबेस सिस्टम में।
उदाहरण के लिए, एक मल्टीथ्रेडिंग प्रोग्राम गतिरोध कर सकता है यदि दो या दो से अधिक धागे उन तालों पर प्रतीक्षा कर रहे हैं जिन्हें पहले अधिग्रहित किया गया था ताकि कोई धागा कोई प्रगति न कर सके। यदि यह जावा अनुप्रयोग में होता है, तो JVM केवल थ्रेड को अपने निष्पादन को रोकने और उसके तालों को छोड़ने के लिए मजबूर नहीं कर सकता है।
यहां तक कि अगर Thread
कक्षा एक stop
विधि को उजागर करती है , तो जावा 1.1 के बाद से उस पद्धति को हटा दिया गया है क्योंकि यह एक थ्रेड के बंद होने के बाद वस्तुओं को असंगत स्थिति में छोड़ सकता है। इसके बजाय, जावा एक interrupt
विधि को परिभाषित करता है , जो एक संकेत के रूप में कार्य करता है जो बाधित हो जाता है और बस रुकावट को अनदेखा कर सकता है और इसके निष्पादन को जारी रख सकता है।
इस कारण से, एक जावा एप्लिकेशन एक गतिरोध की स्थिति से उबर नहीं सकता है, और यह एप्लिकेशन डेवलपर की जिम्मेदारी है कि वह लॉक अधिग्रहण अनुरोधों को इस तरह से आदेश दे कि गतिरोध कभी भी उत्पन्न न हो।
हालांकि, एक डेटाबेस सिस्टम किसी दिए गए लॉक अधिग्रहण आदेश को लागू नहीं कर सकता क्योंकि यह असंभव है कि अन्य लेन-देन एक निश्चित लेनदेन को आगे अधिग्रहित करना चाहते हैं। लॉक ऑर्डर को संरक्षित करना डेटा एक्सेस लेयर की जिम्मेदारी बन जाता है, और डेटाबेस केवल एक डेडलॉक स्थिति से उबरने में सहायता कर सकता है।
डेटाबेस इंजन एक अलग प्रक्रिया चलाता है जो लॉक-वेट साइकल (जो गतिरोध के कारण होता है) के लिए वर्तमान संघर्ष ग्राफ को स्कैन करता है। जब एक चक्र का पता लगाया जाता है, तो डेटाबेस इंजन एक लेन-देन चुनता है और उसे निरस्त कर देता है, जिससे इसके ताले निकल जाते हैं, ताकि दूसरे लेनदेन में प्रगति हो सके।
जेवीएम के विपरीत, एक डेटाबेस लेनदेन कार्य की परमाणु इकाई के रूप में डिज़ाइन किया गया है। इसलिए, एक रोलबैक डेटाबेस को एक सुसंगत स्थिति में छोड़ देता है।
इस विषय के बारे में अधिक जानकारी के लिए, इस लेख को भी देखें।
सार में म्यूटेक्स एक ताला है, जो साझा संसाधनों तक संरक्षित पहुंच प्रदान करता है। लिनक्स के तहत, थ्रेड म्यूटेक्स डेटा प्रकार pthread_mutex_t है। उपयोग करने से पहले, इसे प्रारंभ करें।
साझा संसाधनों तक पहुंचने के लिए, आपको म्यूटेक्स पर लॉक करना होगा। यदि म्यूटेक्स पहले से ही लॉक पर है, तो कॉल थ्रेड को ब्लॉक कर देगा जब तक म्यूटेक्स अनलॉक नहीं हो जाता। साझा संसाधनों की यात्रा पूरी होने पर, आपको उन्हें अनलॉक करना होगा।
कुल मिलाकर, कुछ अलिखित मूल सिद्धांत हैं:
साझा संसाधनों का उपयोग करने से पहले ताला प्राप्त करें।
संभव के रूप में कम समय के लिए ताला पकड़े।
यदि धागा एक त्रुटि देता है तो लॉक को छोड़ दें।