2012-06-16 21 views
6

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686289%28v=vs.85%29.aspxजब सेट थैलाटेबल टाइमर को कॉल करने वाला थ्रेड बाहर निकलता है, जबकि टाइमर पर कोई अन्य थ्रेड इंतजार कर रहा है, तो टाइमर रद्द हो जाता है?

MSDN के अनुसार, टिप्पणी वर्गों में, यह कहा गया है: "अगर धागा कि टाइमर समाप्त सेट और एक संबद्ध पूरा होने दिनचर्या, टाइमर रोक दी गई है हालांकि, टाइमर अवशेषों की राज्य नहीं है। ।। अपरिवर्तित अगर कोई पूरा होने दिनचर्या है, तो धागा समाप्त टाइमर पर कोई प्रभाव नहीं है "

तब और नीचे, यह कहा गया है: " धागा कि SetWaitableTimer बाहर निकलता है कहा जाता है, टाइमर रद्द कर दिया गया है। यह टाइमर को बंद कर देता है इससे पहले कि इसे सिग्नल किए गए राज्य पर सेट किया जा सके और बकाया एपीसी रद्द कर दिया जाए; टाइमर की संकेतित स्थिति नहीं बदलता है। "

इसलिए मेरे सवाल, अगर मैं, एक धागा एक संबद्ध पूरा होने दिनचर्या और एक अन्य धागा बुला WaitOnMultipleObjects (टाइमर वस्तु हैंडल में गुजर) के बिना SetWaitableTimer बुला और धागा कि SetWaitiableTmer उसके बाद शीघ्र ही बाहर निकल जाता है कहता है | टाइमर वस्तु रद्द कर दिया जाएगा या अवधि समाप्त होने पर यह अभी भी संकेतित हो जाएगा?

उत्तर

3

दस्तावेज़ीकरण कुछ हद तक अस्पष्ट है। मुझे लगता है कि आप जो कर सकते हैं वह सबसे अच्छा है। मुझे विश्वास है कि टाइमर स्वचालित रूप से केवल तभी रद्द हो जाता है जब I/O पूरा हो दिनचर्या का उपयोग किया जाता है।

मैं कुछ "सैद्धांतिक" बैकग्राफ दे सकता हूं मेरे (शिक्षित) अनुमान को औचित्य देने के लिए, विंडोज एपीसी के चारों ओर।

एपीसी = "असीमित प्रक्रिया कॉल"। विंडोज़ में प्रत्येक उपयोगकर्ता-मोड थ्रेड एक तथाकथित एपीसी कतार से लैस है, इस थ्रेड पर प्रक्रियाओं की एक सिस्टम-प्रबंधित कतार जिसे कॉल किया जाना चाहिए। एक थ्रेड एक तथाकथित "सतर्क प्रतीक्षा" स्थिति (उद्देश्य पर) दर्ज कर सकता है, जिसके दौरान यह इस कतार में एक या अधिक प्रक्रियाओं को निष्पादित कर सकता है। आप या तो एपीसी कतार में प्रक्रिया कॉल डाल सकते हैं, या I/O जारी कर सकते हैं, जो पूरा होने पर प्रक्रिया कॉल को "डाल" देगा।

सरल शब्दों में परिदृश्य निम्न है: आप कई I/Os जारी करते हैं, और फिर आप उनमें से किसी एक को पूरा करने (या असफल), और शायद, कुछ अन्य घटनाओं के लिए प्रतीक्षा करते हैं। फिर आप सतर्क-प्रतीक्षा कार्यों में से एक को कॉल करते हैं: SleepEx, WaitForMultipleObjectsEx या इसी तरह के।

महत्वपूर्ण नोट: यह तंत्र एकल-थ्रेडेड समेकन का समर्थन करने के लिए डिज़ाइन किया गया है। यही है, वही थ्रेड कई I/Os जारी करता है, कुछ होने की प्रतीक्षा करता है, और उचित प्रतिक्रिया देता है। सभी एपीसी दिनचर्या में समान थ्रेड में कॉल करने के लिए की गारंटी है। इसलिए - अगर यह धागा निकलता है - उन्हें कॉल करने का कोई तरीका नहीं है। इसलिए - सभी बकाया I/Os भी रद्द कर दिए गए हैं।

कई विंडोज एपीआई फ़ंक्शंस हैं जो एसिंक्रोनस I/O से निपटते हैं, जबकि वे कई समापन तंत्र (जैसे ReadFileEx) की पसंद की अनुमति देते हैं: एपीसी, कोई ईवेंट सेट करना, या I/O पूर्णता पोर्ट में पूरा करना । यदि उन कार्यों का उपयोग एपीसी के साथ किया जाता है - यदि जारी करने वाले थ्रेड से बाहर निकलते हैं तो वे स्वचालित रूप से I/O को रद्द कर देते हैं।

इसलिए, मुझे लगता है कि प्रतीक्षा करने योग्य टाइमर केवल एपीसी के साथ उपयोग किए जाने पर ऑटो-कैंसल।

3

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

यदि आप पूर्णता दिनचर्या का उपयोग नहीं कर रहे हैं, तो टाइमर किसी भी थ्रेड की लिंक्ड सूची में कभी नहीं जोड़ा जाता है और इस प्रकार कोई विशेष थ्रेड मरने पर रद्द नहीं किया जाता है।

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