2009-12-30 6 views
6

अपने आवेदन में है दो धागेइंटर-थ्रेड संचार। मैं कैसे एक और धागा करने के लिए एक संकेत भेजने के लिए

  1. एक "मुख्य थ्रेड" जो व्यस्त है समय की सबसे
  2. एक "अतिरिक्त धागा" जो बाहर कुछ HTTP अनुरोध भेजता है और जो तब तक ब्लॉक करता है जब तक यह प्रतिक्रिया प्राप्त न हो जाए।

हालांकि, HTTP प्रतिक्रिया केवल मुख्य धागे द्वारा ही संभाली जा सकती है, क्योंकि यह इसके थ्रेड-स्थानीय-स्टोरेज और गैर-थ्रेडसेफ फ़ंक्शंस पर निर्भर करती है।

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

  • एक तरह से मैं के बारे में सोच सकते हैं कि अतिरिक्त धागा SuspendThread का उपयोग कर मुख्य थ्रेड से निलंबित कर देता है, मुख्य थ्रेड कुछ इनलाइन कोडांतरक का उपयोग करने से प्रतियां टीएलएस, प्रतिक्रिया प्रसंस्करण समारोह में ही निष्पादित करता है और बाद में मुख्य थ्रेड शुरू ।

  • मेरे विचारों में एक और तरीका है, दूसरे थ्रेड कॉलबैक रूटीन में कुछ विशिष्ट पते पर एक ब्रेक पॉइंट सेट करना, ताकि मुख्य थ्रेड अधिसूचित हो जाए जब दूसरे थ्रेड निर्देश पॉइंटर उस ब्रेक पॉइंट पर कदम उठाए - और इसलिए - HTTP प्रतिक्रिया प्राप्त की।

हालांकि, दोनों विधियां अच्छी तरह से प्रतीत नहीं होती हैं, अगर वे केवल उनके बारे में सोचते हैं तो भी उन्हें चोट पहुंचती है, और वे वास्तव में विश्वसनीय नहीं दिखते हैं।

मैं पर अपने मुख्य धागे को बाधित कर सकता हूं, यह कहकर कि यह विनम्र होना चाहिए और कुछ और करने से पहले HTTP प्रतिक्रिया को संसाधित करना चाहिए? पुस्तकालयों पर निर्भरताओं के बिना उत्तर की सराहना की जाती है, लेकिन अगर मैं कुछ अच्छा समाधान प्रदान करता हूं तो मैं कुछ निर्भरता भी लेता हूं।

निम्नलिखित question (QueueUserAPC समाधान के बारे में) के जवाब दिए और समझाया है कि वहाँ मेरे मामले में एक धक्का -behaviour के लिए कोई सुरक्षित तरीका था।

+1

क्या आपको वास्तव में अपने मुख्य धागे को "बाधित" करने की आवश्यकता है? कतार या अन्य कार्य तंत्र से, वैसे भी यह कैसे काम कर रहा है? – sdg

+0

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

+0

आपका मुख्य धागा क्या कर रहा है? क्या यह बाधा है? –

उत्तर

4

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

+0

सिग्नल के साथ जीएनयू/लिनक्स में यह संभव है; हमें बताएं, यह पहली जगह में एक अलग धागे रखने के उद्देश्य को कैसे हराता है? –

0

ऐसा लगता है कि उत्तर माइक्रोसॉफ्ट के MSDN से खोजने योग्य होना चाहिए। विशेष रूप से इस खंड से 'Synchronizing Execution of Multiple Threads'

+0

मुझे अपने मामले में सिंक्रनाइज़ेशन की आवश्यकता नहीं है। मैं चाहता हूं कि किसी अन्य चीज को संसाधित करने के लिए मुख्य थ्रेड के वर्तमान निष्पादन को बाधित करना और इसे बाद में अपने पुराने काम को फिर से शुरू करना है। – Etan

+1

यही 'सिंक्रनाइज़ेशन' का अर्थ है - थ्रेड को एक दूसरे के साथ संवाद करने दें कि वे क्या कर रहे हैं ताकि चीजें व्यवस्थित तरीके से हो सकें। –

+0

आह के, धन्यवाद।मैं * सिंक्रनाइज़ेशन * के तहत समझ गया * महत्वपूर्ण मेमोरी अनुभागों या चीजों तक पहुंच जैसी चीजें जहां आपको किसी अन्य थ्रेड के लिए किसी निश्चित स्थान तक पहुंचने की प्रतीक्षा करनी है। – Etan

1

मुझे प्रश्न समझ में नहीं आ रहा है, लेकिन CreateSemaphore और WaitForSingleObject काम करना चाहिए। यदि एक धागा सेमफोर के लिए इंतजार कर रहा है, तो यह फिर से शुरू होगा जब अन्य थ्रेड इसे संकेत देगा।

टिप्पणी के आधार पर अद्यतन: मुख्य धागा शून्य के प्रतीक्षा समय के साथ WaitForSingleObject को कॉल कर सकता है। उस स्थिति में, अगर सैमफोर संकेत नहीं दिया जाता है तो यह तुरंत फिर से शुरू हो जाएगा। मुख्य धागा इसे आवधिक आधार पर देख सकता है।

+0

मुख्य धागे को HTTP प्रतिक्रिया के लिए इंतजार नहीं करना चाहिए, जैसे ही HTTP प्रतिक्रिया आती है, ** इसे ** बाधित ** होना चाहिए। किसी भी समय! अगर कोई प्रतिक्रिया नहीं थी, तो इसे सामान्य निष्पादन जारी रखना चाहिए। – Etan

+0

मुझे लगता है कि अब मैं समझता हूं। मुझे यह भी नहीं लगता कि ऐसा करने का कोई तरीका है ... कम से कम एक साफ फैशन में। मुझे लगता है कि आप थ्रेड में अपवाद को मजबूर कर सकते हैं ताकि वह इसे रोक सके। फिर से शुरू करना एक समस्या होगी। यह मुझे लगता है कि अगर चीजों को इस तरह से काम करना चाहिए तो एक वास्तुशिल्प समस्या है। –

+0

मुझे लगता है कि मार्कव ने क्या कहा सही है। WaitForSingleObject आपकी समस्या को हल कर सकता है अगर मैं आपका प्रश्न ठीक से समझ रहा हूं। – Abhineet

0

यदि आपका मुख्य धागा जीयूआई थ्रेड है तो इसे विंडोज़ संदेश क्यों न भेजें? कार्यकर्ता धागे से Win32 GUI के साथ बातचीत करने के लिए हम सभी क्या करते हैं।

+0

मुख्य धागा एक जीयूआई धागा नहीं है। हालांकि, एक संदेश कतार की अवधारणा अच्छी लगती है! अफसोस की बात है, यह अतिरिक्त धागे से "धक्का" -मेचनवाद के बजाय मुख्य धागे से "पुल" -मेचनिज्म पर भी आधारित है। – Etan

+0

हां, लेकिन वह जो बहुत अच्छी तरह से काम करता है। वैसे भी आपका मुख्य धागा क्या कर रहा है? – sdg

+0

यदि आपका धागा जीयूआई थ्रेड नहीं है तो आप उसी परिणाम को प्राप्त करने के लिए PostThreadMessage का उपयोग कर सकते हैं। लेकिन निश्चित रूप से आप किसी भी संदेश क्यूइंग तंत्र का उपयोग करने के लिए स्वतंत्र हैं जो आपके उद्देश्यों के अनुरूप है। –

0

यह निर्धारित करने का एक तरीका है कि समय-समय पर जांच करें कि HTTP प्रतिक्रिया प्राप्त हुई है या नहीं।

आप कहने के लिए आप क्या हासिल करने की कोशिश कर रहे हैं यह बेहतर है।

2

आप क्या वर्णन कर रहे हैं क्या QueueUserAPC करता है। लेकिन इस तरह के सिंक्रनाइज़ेशन के लिए इसका उपयोग करने की धारणा मुझे थोड़ा असहज बनाती है। यदि आपको नहीं पता कि मुख्य धागा सुरक्षित स्थान को बाधित करने के लिए है, तो आपको शायद इसे बाधित नहीं करना चाहिए।

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

PostMessage या PostThreadMessage आमतौर पर आपके मुख्य धागे पर काम की बिट्स को सौंपने के लिए वास्तव में अच्छा काम करता है। पोस्ट किए गए संदेश उपयोगकर्ता इनपुट संदेशों से पहले संभाले जाते हैं, लेकिन जब तक धागा उनके लिए तैयार न हो जाए।

+0

मैंने इसे 'QueueUserAPC' के साथ करने की कोशिश की। हालांकि, यह मेरे अन्य [प्रश्न] के रूप में काम नहीं कर रहा है (http://stackoverflow.com/questions/1980145/callback- निर्दिष्ट-in-queueuserapc-does-not-get-called) राज्यों। – Etan

+1

मुख्य धागे को केवल एपीसी चलाने के लिए उधार लिया जा सकता है जब यह कर्नेल में होता है, आमतौर पर ऐसा होता है जब आप आईओ कर रहे होते हैं। –

0

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

एक बार जब आप उस जगह में आप अनिवार्य रूप से अपने मुख्य थ्रेड रन काम के प्रत्येक टुकड़े के ऊपर एक पाश में समय-समय पर जाँच अगर वहाँ कतार में संभाल करने के लिए अनुरोध कर रहे हैं देखने के लिए कर सकते हैं, कर सकते है। लंबे समय तक एक आर्किटेक्चर के बारे में अच्छा क्या है कि आप थ्रेड स्थानीयकृत स्टोरेज को काफी आसानी से खत्म कर सकते हैं और स्लिस्ट को एक कतार में परिवर्तित करके मुख्य थ्रेड को समानांतर कर सकते हैं (शायद अभी भी स्लीस्ट का उपयोग कर), और काम के छोटे टुकड़े बनाना और कार्य वस्तुओं में प्रतिक्रिया जो किसी भी उपलब्ध थ्रेड में गतिशील रूप से वितरित की जा सकती हैं।