2012-02-06 18 views
8

मैं लगातार मेमोरी मैप की गई फ़ाइल से पढ़ रहा हूं, दूसरी प्रक्रिया इस ऑपरेशन को सिंक्रनाइज़ करने के लिए एक म्यूटेक्स को लिख रही है और उपयोग कर रही है। मेरे कुछ परीक्षणों में अब तक यह ठीक काम करता है, लेकिन ... क्या होगा यदि मेरा आवेदन म्यूटेक्स प्राप्त करने के बाद और इसे जारी करने के ठीक बाद दुर्घटनाग्रस्त हो जाए? क्या इस तरह के दुर्घटना के मामले में म्यूटेक्स की रिहाई की गारंटी देने का कोई तरीका है?एक म्यूटेक्स की "सुरक्षित" हैंडलिंग?

इसके अलावा मैं अन्य प्रक्रिया के दुर्घटना को कैसे संभालेगा, जिसने अभी तक म्यूटेक्स जारी नहीं किया हो सकता है? जब भी मैं mutex.WaitOne() को कॉल करता हूं, तो क्या मुझे हर बार AbandonedMutexException को संभालने की आवश्यकता है?

अभी मैं इसे इस के समान कर रहा हूँ:

public MyState GetState() 
{ 
    MyState state = new State(); 
    this._mutex.WaitOne(); 
    try 
    { 
     state.X = this._mmView.ReadSingle(0); 
     state.Y = this._mmView.ReadSingle(4); 
     [..] 
    } 
    finally 
    { 
     this._mutex.ReleaseMutex(); 
    } 
    return state; 
} 

_mmView एक MemoryMappedViewAccessor मैंने पहले instantiated है। यह पूरी विधि गेटस्टेट() प्रत्येक फ्रेम को गेम लूप के हिस्से के रूप में बुलाया जाता है, इसलिए प्रत्येक कुछ मिलीसेकंड के बारे में।

पीएस: इसके अलावा, क्या कोई अन्य स्पष्ट समस्या है कि यह असफल क्यों हो सकता है, मैंने पहले ही उल्लेख नहीं किया था?

उत्तर

11

यूजेन के जवाब सही है - आपके लिए ऑपरेटिंग सिस्टम म्युटेक्स जारी करेंगे। अब के बारे में क्या इस तथ्य का परिणाम हैं कठिन लगता है:

  • आप यह सुनिश्चित करें कि कोई भी राज्य उत्परिवर्तित होगा जबकि आप पढ़ रहे थे, या राज्य पढ़ा जब तुम परिवर्तनशील थे म्युटेक्स निकाल लिया। आइए बाद वाले का मान लें।
  • एक और आवेदन राज्य को पढ़ना चाहता है, इसलिए यह म्यूटेक्स लेने की कोशिश करता है। इसे इंतजार करने के लिए मजबूर किया जाता है।
  • आपने कुछ राज्य को बदल दिया और फिर दुर्घटनाग्रस्त हो गया।
  • ऑपरेटिंग सिस्टम ने म्यूटेक्स जारी किया।
  • अन्य एप्लिकेशन अब तुरंत म्यूटेक्स, प्राप्त करता है और अब प्रभावी रूप से राज्य पढ़ रहा है "जबकि" दूसरी प्रक्रिया इसे पर उत्परिवर्तित कर रही है। तथ्य यह है कि दूसरी प्रक्रिया अब मर चुकी है और चला गया है कि फर्जी राज्य अब हमेशा तक टिकेगा, और पढ़ने की प्रक्रिया शायद ही दुर्घटनाग्रस्त हो जाएगी और बहुत ही मर जाएगी। आपने म्यूटेक्स द्वारा प्रदान की गई सुरक्षा प्रणाली को अभी हराया है।

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

पहले स्थान पर उस स्थिति में न आएं।समस्या का समाधान क्रैश न करें जब आपने लिखने के लिए एक म्यूटेक्स निकाला है। यदि आप क्रैश किए गए प्रोग्राम नहीं लिखते हैं तो आपको इसके बारे में चिंता करने की ज़रूरत नहीं है, क्योंकि ऐसा नहीं होने वाला है। तो बस उन प्रोग्रामों को न लिखें जो कभी दुर्घटनाग्रस्त हो जाते हैं।

+3

"प्रोग्राम कभी भी क्रैश न करें", या ज़ेन मास्टर ने कहा - "त्रुटि से बचें।" अच्छी सलाह। अहम। – mickeyf

+1

हालांकि बहुत मजबूत और न ही यथार्थवादी लगता है। क्या होगा यदि उपयोगकर्ता बस कार्य प्रबंधक के माध्यम से प्रक्रिया को मारता है, जबरन ऐप को दुर्घटनाग्रस्त कर देता है? – Mario

+7

@ मारियो: मुझे नहीं पता कि आपको क्या लगता है अवास्तविक है; मैं आपको आश्वासन देता हूं कि डेटा के इस तरह के भ्रष्टाचार कीड़े अक्सर फसल उगती हैं और यदि आप उपयोगकर्ता के डेटा की स्थिति की परवाह करते हैं तो इसके खिलाफ संरक्षित होना चाहिए। पुन: क्या होगा यदि उपयोगकर्ता ऐप को दुर्घटनाग्रस्त करता है? आप मुझसे पूछ रहे हैं कि क्या होता है जब उपयोगकर्ता ऐसी सामग्री करता है जो अपने डेटा को दूषित करता है? ** उनका डेटा दूषित हो गया **, यही है। वे उपयोगकर्ता जो नहीं चाहते हैं कि उनका डेटा दूषित हो ** ** अपने ऐप्स को नीचे नहीं लेना चाहिए **। एक * कारण * ऐसा क्यों कर रहा है एक संवाद बॉक्स रखता है जो कहता है "यदि आप ऐसा करते हैं तो आप अपना डेटा दूषित कर सकते हैं"। –

2

जब एक म्यूटेक्स के मालिक होने पर एक प्रक्रिया समाप्त होती है, तो ओएस स्वचालित रूप से आपके लिए म्यूटेक्स जारी कर देगा। Mutex को एक्वायर करके और फिर raise new WhateverException() - इसे अन्य प्रक्रिया जारी रखकर इसे आज़माएं।

ही सब सिंक पुरातन के लिए सच है AFAIK