2009-03-07 8 views
6

यह:कर सकते हैं एक भी SetEvent() ट्रिगर कई WaitForSingleObject()

http://msdn.microsoft.com/en-us/library/ms686915(VS.85).aspx

नहीं सुझाव देने के लिए प्रतीत होता है।

मेरे पास पाइप के माध्यम से संचार करने वाली तीन प्रक्रियाएं हैं। प्रक्रिया ए एक घटना बनाता है, प्रक्रिया बी & सी प्रत्येक का उपयोग WaitForSingleObject (दूसरे थ्रेड में) का उपयोग करता है।

तो अब हमारे पास -TWO- प्रत्येक-सिंगल-ईवेंट के लिए प्रतीक्षा करने की प्रक्रिया करता है।

प्रक्रिया ए SetEvent(), प्रक्रिया बी प्रतिक्रिया के साथ घटना को आग लगती है, प्रक्रिया सी नहीं करता है।

निष्कर्ष:

प्रत्येक WaitForSingleObject() एक अद्वितीय घटना की आवश्यकता है ... है न?

उत्तर

5

एकल ईवेंट से कई धागे को ट्रिगर करने के लिए मैन्युअल रीसेट ईवेंट का उपयोग करें।

Here एक उदाहरण जो आप धागे वर्तमान में घटना के लिए इंतजार कर के सभी को रिहा करने मैनुअल रीसेट Evenets और PulseEvent समारोह का उपयोग कर सकते का उपयोग करता है "मैनुअल रीसेट घटना" झंडा

+0

दुर्भाग्यवश मेरे पास प्रक्रिया ए पर कोई नियंत्रण नहीं है इसलिए मैं इसे लागू नहीं कर सकता। –

2

है।

नोट हालांकि, यह दृष्टिकोण स्वाभाविक रूप से कठोर है, क्योंकि यह कहने का कोई तरीका नहीं है कि "वर्तमान में मौजूद धागे ..." हैं। यदि वेकअप/2 प्रतीक्षा घटनाओं की सटीक मिलान की आवश्यकता है तो आपको अधिक विश्वसनीय सिंक्रनाइज़ेशन तंत्र का उपयोग करना चाहिए।

+0

मैंने इसका जिक्र नहीं किया, लेकिन मेरे पास प्रक्रिया ए पर कोई नियंत्रण नहीं है, लेकिन मैं भविष्य के संदर्भ के लिए पल्ससेवेंट फ़ंक्शन को देखूंगा .. धन्यवाद। –

+0

यदि आप केवल बी एंड सी धागे बदल सकते हैं, तो ए बीटीडब्लू से सभी धागे को जगाने की कोशिश करने के बजाय दूसरे थ्रेड (यानी ए -> बी -> सी) से एक थ्रेड उठाना सबसे अच्छा होगा, अगर आप नहीं करते हैं नियंत्रण ए, आपके पास कुछ लॉकिंग/वेकअप प्रोटोकॉल/इंटरफ़ेस होना चाहिए, और इस प्रश्न में इसका उल्लेख करें। – jpalecek

+1

PulseEvent का उपयोग न करें, http://blogs.msdn.com/oldnewthing/archive/2005/01/05/346888.aspx – CesarB

0

मुझे आशा है कि इस उदाहरण आप मदद कर सकते हैं:

handle1A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME) 

handle1B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME) 

handle2A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId()) 

handle2B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId()) 

ए) यदि आप एक ही NAME के साथ एक ईवेंट बनाते हैं, हर setEvent संकेत सभी waitforsingleobjects

SetEvent(handle1A) // Send signaling to handle1A and handle1B 

बी) यदि आप एक घटना बनाने जबकि एक अद्वितीय NAME, setEvent केवल संदर्भित हैंडल को संदर्भ भेजता है

SetEvent(handle2) // Send signling only to handle2A. The Id Thread is unique 
0

यदि कोई मैन्युअल रीसेट ईवेंट है तो एक ईवेंट एकाधिक थ्रेड को सूचित कर सकता है। एक ऑटो-रीसेट ईवेंट ऐसा नहीं कर सकता है। यदि एक से अधिक ट्रेड एक ऑटो-रीसेट ईवेंट के लिए एक साथ प्रतीक्षा कर रहे हैं, और आप इसे सिग्नल किए गए स्थिति में सेट करते हैं, तो केवल एक थ्रेड मौजूद है और इसे रीसेट करता है, और अन्य धागे का व्यवहार अपरिभाषित होगा। हालांकि, माइक्रोसॉफ्ट प्रलेखन से, हम मान सकते हैं कि एक और केवल एक धागा बाहर निकल जाएगा जबकि अन्य निश्चित रूप से बाहर नहीं निकलेंगे। वैसे भी, हमें निम्नलिखित उद्धरण को ध्यान में रखना चाहिए: "पहले-इन, फर्स्ट-आउट (एफआईएफओ) ऑर्डर को न मानें। कर्नेल-मोड एपीसी जैसे बाहरी कार्यक्रम प्रतीक्षा आदेश बदल सकते हैं "स्रोत - https://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx

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

PulseEvent के बारे में के रूप में - यह अविश्वसनीय है और कभी नहीं इस्तेमाल किया जाना चाहिए - देखना https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914(v=vs.85).aspx

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

आप ऑटो के बारे में अधिक विचार प्राप्त कर सकते हैं: आप निम्न लिंक पर कर्नेल-मोड अतुल्यकालिक प्रक्रिया कॉल (APC) के बारे में और अधिक जानकारी प्राप्त कर सकते हैं निम्न आलेखों से ईवेंट और मैन्युअल रीसेट ईवेंट रीसेट करें:

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