2012-10-01 15 views
7

मैं कुछ डिबग एक CRITICAL_SECTION अनलॉक करने का कोड की जाँच जोड़ने की कोशिश कर रहा हूँ, और मैं निम्नलिखित की कोशिश की: (वी.एस. 2005 के साथ, ज्यादातर है Windows XP पर) CRITICAL_SECTIONS डिबगिंग मैं "पता" सेCRITICAL_SECTION प्रकार के हैंडल का स्वामित्व थ्रेड सदस्य क्यों है, जब यह थ्रेड आईडी को इंगित कर रहा है?

... 
    if (m_pCritSect) { 
    ASSERT(m_pCritSect->OwningThread == GetCurrentThreadId()); 
    LeaveCriticalSection(m_pCritSect); 
    } 
} 

कि का मान OwningThread (RTL_CRITICAL_SECTION संरचना winnt.h में परिभाषित संरचना का सदस्य) लॉक रखने वाले थ्रेड के आईडी का मान है।

हालांकि सूत्र आईडी (unsigned long के लिए typedef) DWORD का प्रतिनिधित्व कर रहे मूल्यों जबकि इस वैरिएबल प्रकार HANDLE (void* के लिए typedef) है ऊपर कोड काम करने के लिए एक reinterpret_cast के लिए HandleToULongbasetsd.h से मैक्रो के उपयोग की आवश्यकता होती है।

भी MSDN docs राज्य:

पहले धागा EnterCriticalSection दिनचर्या आवश्यकता होने पर, (...) OwningThread करने वाले का धागा आईडी हो जाता है।

तो पृथ्वी पर क्यों इसे HANDLE के रूप में परिभाषित किया गया है?


संपादित करें नोट: मैं a statement पाया जहां एक पोस्टर पता चलता है कि हैंडल/DWORD-ईद बेमेल कुछ Windows internals के कुछ ज्ञात misfeature है। तो शायद इस मामले यहाँ भी है:

GetCurrentThreadId एक DWORD, जो मैं एक संदेश में गिरी अप करने के लिए भेज देता है। PsLookupThreadByThreadId, एक हैंडल में धागा आईडी लेता है ... ...

यह एक ज्ञात Windows API बग ("ज्ञात" है कि मैं इस बारे में प्रासंगिक फिल्टर प्रबंधक देव से बात की, के रूप में यह में दिखाई देता है में है फ़िल्टर करें प्रबंधक I/O प्रबंधक API समस्या के कारण भी।) जब तक आप में आधे बिलियन या उससे अधिक धागे और प्रक्रियाएं नहीं हैं (वे एक साझा साझा हैंडल तालिका का उपयोग करें) तो आप ठीक होंगे । शायद द्वारा यह एक वास्तविक मुद्दा है, हम कुछ अलग चलेंगे। [आरई: 64 बिट के लिए हैंडल के लिए ThreadId?, 08 अगस्त 08 14:21, टोनी मेसन]

+1

किसी भी मामले में reinterpret_cast अधिक है। एक static_cast करेंगे। हैंडल और डीडब्ल्यूओआर दोनों अभिन्न प्रकार हैं। –

+0

@ArmenTsirunyan - नहीं, वीएस2005 में आप एक हैंडल को एक डंडर में डालने के लिए static_cast का उपयोग नहीं कर सकते: 'त्रुटि C2440:' static_cast ':' हैंडल 'से' DWORD '' –

+0

में परिवर्तित नहीं हो सकता है यह अजीब है। क्या आप कृपया मुझे बता सकते हैं कि वे किस प्रकार टाइप किए गए हैं? –

उत्तर

8

एसडीके जिसका नाम में कोई पहचानकर्ता RTL साथ शुरू होता है या RTL कोड या घोषणाओं कि क्रम का हिस्सा हैं है परत, गोंद जो अच्छी तरह से प्रलेखित विनपी से अनियंत्रित देशी ऑपरेटिंग सिस्टम एपीआई से शादी करती है। Winapi पत्थर में डाला गया है, देशी ऑपरेटिंग सिस्टम प्रत्येक विंडोज रिलीज के साथ भारी बदलता है। अनिवार्य रूप से, गोंद भी बदलता है।

विनपी दस्तावेज वाली परत है, मूल ऑपरेटिंग सिस्टम अनियंत्रित है। रनटाइम परत को भी अनियंत्रित किया गया था, लेकिन इसके समय के हिस्सों के बारे में पता चला था। या तो क्योंकि यह winapi में एक लापता सुविधा भर देता है। या, इस मामले में, क्योंकि समस्याओं का निवारण करने के लिए वास्तव में उपयोगी है। ऐसा करने में एक मूल समस्या यह है कि एक बार घोषणा घोषित होने के बाद, माइक्रोसॉफ्ट इसे फिर से नहीं बदल सकता है। ऐसा करने से मौजूदा कार्यक्रमों को तोड़ दिया जाएगा, जो अपने ग्राहकों के लिए एक बड़ा बोझ है।

तो निश्चित रूप से, थ्रेडऑनर फ़ील्ड एक बार वास्तव में पिछले विंडोज संस्करण में थ्रेड को हैंडल रखता था। ध्यान दें कि लॉकसेमफोर भी भ्रामक है, यह वास्तव में एक ऑटो-रीसेट ईवेंट है। इसे ठीक करने में बहुत देर हो चुकी है, बिल्ली बैग से बाहर है।

4

मेरा मानना ​​है कि मुख्य कारण यह है कि यह एक कार्यान्वयन विस्तार है। मुझे आश्चर्य नहीं होगा अगर इतिहास में एक समय में यह वास्तव में एक हैंडल या ऐसा कुछ था।

इसके अतिरिक्त, मैं दृढ़ता से सुझाव देता हूं कि उत्पादन कोड में आंतरिक सदस्यों का उपयोग न करें और I am not alone। तुम करीब से देखो, तो सिंक्रनाइज़ेशन एपीआई CRITICAL_SECTION जो आप MSDN में एक संरचना, और नहीं RTL_CRITICAL_SECTION (जो CRITICAL_SECTION को typedef'ed है)

जो OwningThread सदस्य में संग्रहीत किया जाता मूल्य CLIENT_ID से लिया जाता है के रूप में दस्तावेज प्राप्त नहीं कर सकेंगे का उपयोग Thread Information Block का हिस्सा।CLIENT_ID में यह रूप में जो संभावना है क्यों यह CRITICAL_SECTION भीतर उसी तरह से मॉडलिंग की है PVOID के रूप में मॉडलिंग की:

typedef struct _CLIENT_ID 
{ 
    PVOID UniqueProcess; 
    PVOID UniqueThread; 
} CLIENT_ID, *PCLIENT_ID; 
+0

मैंने एक एमएसडीएन लिंक प्रदान किया जो इस संरचना के माध्यम से चलता है (यह * उन्नत डिबगिंग कार्य * अनुभाग में दिया गया है) इसलिए मुझे लगता है कि यह * डीबग चेकिंग कोड * में इसका उपयोग करना ठीक है। –

+0

संरचना में बदलाव होने पर यह अभी भी निर्माण नहीं करेगा, और मैं एएसएसईआरटी कोड वास्तविक उत्पादन कोड पर भी विचार नहीं करता, क्योंकि यह अंतिम उपयोगकर्ता (यानी रिलीज बिल्ड में) पर तैनात नहीं है। –

संबंधित मुद्दे