2011-12-18 21 views
14

मैं समझते हैं कि एक एपीसी है, यह कैसे काम करता करते , और कैसे विंडोज इसे इस्तेमाल करता है, लेकिन मुझे समझ नहीं आता जब मैं (एक प्रोग्रामर के रूप) के बजाय QueueUserAPC का उपयोग करना चाहिए, कहते हैं, एक फाइबर, या धागा पूल धागा।QueueUserAPC() का उपयोग कब करें?

मुझे QueueUserAPC का उपयोग कब करना चाहिए, और क्यों?

+1

यह विंडोज संदेश लूप का निम्न-स्तर समकक्ष है। यह आपको एक सुरक्षित तरीके से थ्रेड में कोड इंजेक्ट करने देता है। धागा संकेत देता है कि यह एक सतर्क प्रतीक्षा को निष्पादित करके पुन: प्रवेश से निपटने के लिए तैयार है। GetMessage() को कॉल करने की तरह। –

+0

@ हंसपैसेंट: हमम ... मुझे ऐसा लगता है, लेकिन मुझे नहीं लगता कि यह GetMessage() जैसा है। GetMessage बस एक संदेश पुनर्प्राप्त करता है, जबकि QueueUserAPC * कॉल * विधि - तो यह एक ढेर ओवरफ्लो का कारण बन सकता है, है ना? वे अलग दिखते हैं ... – Mehrdad

+0

बस सभी को याद रखना चाहिए कि "GetMessage" एक सतर्क प्रतीक्षा नहीं है।और @Mehrdad, कोई QueueUserAPC विधि को तब तक नहीं बुलाएगा जब तक थ्रेड उनको संभालने के लिए तैयार न हो जो हमेशा स्रोत कोड – Lothar

उत्तर

15

QueueUserAPC एक साफ उपकरण है जो अक्सर कुछ कार्यों के लिए शॉर्टकट हो सकता है जो अन्यथा सिंक्रनाइज़ेशन ऑब्जेक्ट्स के साथ संभाले जाते हैं। यह आपको उस थ्रेड के लिए सुविधाजनक होने पर किसी विशेष थ्रेड को कुछ करने के लिए अनुमति देता है (यानी जब यह अपना वर्तमान काम पूरा करता है और कुछ पर इंतजार करना शुरू करता है)।

मान लें कि आपके पास मुख्य धागा और कार्यकर्ता धागा है। कार्यकर्ता थ्रेड एक फ़ाइल सर्वर पर सॉकेट खोलता है और एक लूप में recv() को कॉल करके 10GB फ़ाइल डाउनलोड करना प्रारंभ करता है। मुख्य धागा वर्कटाइम थ्रेड को अपने डाउनटाइम में कुछ और करना चाहता है जबकि यह नेट पैकेट की प्रतीक्षा कर रहा है; यह कार्यकर्ता पर चलाने के लिए एक समारोह को कतारबद्ध कर सकता है जबकि यह अन्यथा इंतजार कर रहा है और कुछ भी नहीं कर रहा है।

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

ऐसा लगता है जब आपके पास कॉल डेस्क कर्मचारी बैठे और फोन कॉल की प्रतीक्षा कर रहा है, और आप उस व्यक्ति को अपने डाउनटाइम के दौरान करने के लिए छोटे कार्य देते हैं। "यहां, जब आप प्रतीक्षा कर रहे हों तो इस रुबिक के घन को हल करें।" हालांकि, जब एक फोन कॉल आता है, तो व्यक्ति फोन का जवाब देने के लिए रुबिक के घन को नहीं डालेगा (एपीसी को थ्रेड से पहले वापस लौटना पड़ सकता है)।

QueueUserAPC भी उपयोगी है यदि कोई डेटा थ्रेड (थ्रेड ए) है जो कुछ डेटा संरचना के प्रभारी है, और आप डेटा संरचना पर किसी अन्य थ्रेड (थ्रेड बी) से कुछ ऑपरेशन करना चाहते हैं, लेकिन आप ' टी उस धागे को दो धागे के बीच साझा करने की कोशिश करने की सिंक्रनाइज़ेशन ओवरहेड/जटिलता चाहते हैं। थ्रेड बी को थ्रेड ए पर चलाने के लिए ऑपरेशन को कतारबद्ध करके, जो पूरी तरह से उस संरचना को बनाए रखता है, आप उस डेटा पर सिंक्रनाइज़ेशन के बारे में चिंता किए बिना किसी भी मनमानी फ़ंक्शन को निष्पादित कर रहे हैं।

यह थ्रेड पूल की तरह एक और टूल है। हालांकि एक थ्रेड पूल के साथ आप किसी विशेष धागे को कोई कार्य नहीं भेज सकते हैं। काम पूरा होने पर आपका कोई नियंत्रण नहीं है। जब आप एक ऐसे कार्य को कतारबद्ध करते हैं जो एक नया नया धागा बना सकता है। आप दो कार्यों को कतारबद्ध कर सकते हैं और वे दो अलग-अलग धागे पर एक साथ किया जाता है। QueueUserAPC के साथ, आप गारंटी दे सकते हैं कि कार्य क्रम में और आपके द्वारा निर्दिष्ट धागे पर किए जाएंगे।

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