सर्वर एप्लिकेशन पर हमारे पास निम्न है: एक कक्षा जिसे जॉबमेनगर कहा जाता है जो सिंगलटन है। एक और वर्ग, शेड्यूलर, जो यह जांचता रहता है कि क्या यह जॉबमेनगर को किसी भी तरह की नौकरी जोड़ने का समय है। एक ही समय मेंडेडलॉक डेल्फी स्पष्टीकरण/समाधान
TJobManager.Singleton.NewJobItem(parameterlist goes here...);
, क्लाइंट अनुप्रयोग पर, उपयोगकर्ता कुछ है कि सर्वर के लिए एक ऐसा कॉल करें:
जब यह ऐसा करने के लिए समय है, समयबद्धक की तरह कुछ है। आंतरिक रूप से, सर्वर स्वयं को एक संदेश भेजता है, और उस संदेश को सुनने वाले वर्गों में से एक जॉबमेनगर है। JobManager संदेश संभालती है, और जानता है कि यह सूची में एक नया काम को जोड़ने के लिए, अपने स्वयं के विधि बुला समय आ गया है:
CS.Acquire;
try
DoSomething;
CallAMethodWithAnotherCriticalSessionInternally;
finally
CS.Release;
end;
:
NewJobItem(parameter list...);
NewJobItem विधि पर, मैं कुछ इस तरह है
ऐसा होता है कि सिस्टम इस बिंदु पर एक डेडलॉक तक पहुंचता है (सीएस.एक्वायर)। क्लाइंट और सर्वर अनुप्रयोग के बीच संचार इंडी 10 के माध्यम से किया जाता है। मुझे लगता है कि आरपीसी कॉल जो सर्वर अनुप्रयोग विधि को आग लगती है जो जॉबमैनेजर को संदेश भेजती है, इंडी थ्रेड के संदर्भ में चल रही है।
शेड्यूलर का अपना धागा चल रहा है, और यह जॉबमेनगर विधि को सीधा कॉल करता है। क्या यह स्थिति डेडलॉक्स से ग्रस्त है? क्या कोई मुझे समझने में मदद कर सकता है कि यहां एक डेडलॉक क्यों हो रहा है?
हम जानते थे कि, कभी-कभी, जब ग्राहक ने एक विशिष्ट कार्यवाही की, तो सिस्टम को लॉक करने का कारण बनता है, तो आखिरकार मैं इस बिंदु को ढूंढ सकता हूं, जहां एक ही कक्षा में महत्वपूर्ण वर्ग अलग-अलग बिंदुओं से दो बार पहुंच जाता है (जॉबमैनेजर का शेड्यूलर और संदेश हैंडलर विधि)।
कुछ अधिक जानकारी
मैं जोड़ने के लिए है कि चाहते हैं (यह मूर्खतापूर्ण हो सकता है लेकिन वैसे भी ...) DoSomething अंदर एक और
CS.Acquire;
try
Do other stuff...
finally
CS.Release;
end;
यह आंतरिक CS.Release कर रहा है बाहरी सीएस के लिए कुछ भी। पूछताछ? यदि ऐसा है, तो यह वह बिंदु हो सकता है जहां शेड्यूलर गंभीर अनुभाग में प्रवेश कर रहा है, और सभी लॉक और अनलॉक गड़बड़ हो जाता है।
एक गंभीर खंड का उद्देश्य कोड की रक्षा करना है जिसे अलग-अलग धागे पर एक ही समय में निष्पादित नहीं किया जा सकता है, इसलिए यह ठीक है और अच्छा है यदि एक ही उदाहरण पर एक महत्वपूर्ण खंड दो बार (या अधिक) तक पहुंच जाता है क्योंकि इसका मतलब है महत्वपूर्ण अनुभाग यह काम कर रहा है और इसके लिए डिजाइन किया गया है! बुरी बात यह है कि जब सीएस 1 रिलीज नहीं होता है क्योंकि यह थ्रेड प्राप्त कर रहा है तो सीएस 2 हासिल करने का इंतजार कर रहा है, जबकि सीएस 2 रिलीज नहीं होता है क्योंकि यह थ्रेड प्राप्त कर रहा है सीएस 1 (डेडलॉक कहा जाता है) हासिल करने का इंतजार कर रहा है। आप जो कहते हैं उससे, मुझे यकीन नहीं है कि आप डेडलॉक का अनुभव कर रहे हैं ... आप निश्चित क्यों हैं? – jachguate
संदेश हैंडलर विधि के बाद, डीबगिंग करते समय, मैंने महत्वपूर्ण अनुभाग में प्रवेश किया, और सीएस.एक्वायर लाइन पर मेरा ब्रेक पॉइंट, फिर से पहुंचा, शेड्यूलर से आ रहा था - एफ 8 को फिर से मार रहा था, सिस्टम बंद हो गया। – ronaldosantana
आप विंडोज़ संदेश हैंडलिंग लूप पर भी डेडलॉक कर सकते हैं।जब थ्रेडए को सीएस 1 पर लॉक था और फिर एक कॉल करता है जिसके लिए संदेश लूप को लूप की आवश्यकता होती है; और थ्रेड बी प्रभावी रूप से सीएस 1 प्राप्त करने के इंतजार के दौरान संदेश लूप को रोकना, बाधित करना, या अनिश्चित काल में देरी कर रहा है ... –