2008-10-16 5 views
7

मेरे पास एक सी ++ Win32 एप्लिकेशन है जिसमें कई थ्रेड हैं जो आईओ (HTTP कॉल इत्यादि) करने में व्यस्त हो सकते हैं जब उपयोगकर्ता एप्लिकेशन को बंद करना चाहता है। वर्तमान में, मैं अच्छी तरह से खेलता हूं और main से लौटने से पहले सभी धागे को समाप्त करने की प्रतीक्षा करता हूं। कभी-कभी, मुझे जितना चाहें उतना समय लगता है और वास्तव में, जब उपयोगकर्ता बाहर निकल सकता है तो उपयोगकर्ता को प्रतीक्षा करने के लिए यह व्यर्थ लगता है। हालांकि, अगर मैं आगे बढ़ता हूं और main से वापस लौटाता हूं, तो मुझे क्रैश होने की संभावना है क्योंकि विनाशकों को ऑब्जेक्ट्स का उपयोग करके धागे अभी भी बुलाए जाने लगते हैं।मैं अपने Win32 ऐप के तेज़ शटडाउन की गारंटी कैसे दूं?

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

उत्तर

2

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

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

-5

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

व्यक्तिगत रूप से, मैं उपयोगकर्ता को केवल कंप्यूटर को अनप्लग करने के लिए निर्देश पसंद करता हूं। :)

+0

एक मजाकिया जवाब दें, अस्थियों के नीचे संशोधित हो जाएं, ऐसा लगता है ... लोगों को हास्य का कोई मतलब नहीं है ... – tloach

+0

हाँ, मुझे चोट लगी है। शायद उनके ढेर बह गया। –

+1

डीआईजीजी या स्लेशडॉट वेवे हैं -----> – jim

0

यदि आप प्लग को गड़बड़ाना चाहते हैं, तो बाहर निकलें (0) चाल करेगा।

+0

थ्रेडेड अनुप्रयोगों के लिए आईआईआरसी, आपको बाहर निकलने के बजाय _exit() को कॉल करने की आवश्यकता है। मैं इसके लिए प्रलेखन की तलाश में था लेकिन मुझे इस समय यह नहीं मिल रहा है। – paxos1977

2

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

+1

यदि आपका मतलब है "मुख्य विंडो को अदृश्य मोड में सेट करना" तो यह मूल समस्या को ठीक नहीं करेगा, केवल कॉस्मेटिक होने पर। इसके अलावा, प्रश्न धागे को अभी रोकने के बारे में है, छिपाने के लिए नहीं वे अभी भी चल रहे हैं। –

7

ओवरलैप्ड आईओ का उपयोग करें ताकि आप हमेशा अपने आई/ओ से निपटने वाले धागे के नियंत्रण में रह सकें और हमेशा उन्हें किसी भी बिंदु पर रोक सकें; आप या तो उन्हें आईओसीपी पर इंतजार कर रहे हैं और इसे एप्लिकेशन स्तर शट डाउन कोड पोस्ट कर सकते हैं, या आप अपने ओवरलैप्ड स्ट्रक्चर में ईवेंट पर इंतजार कर सकते हैं और अपने 'सभी थ्रेड्स को अभी बंद करें' ईवेंट पर भी इंतजार कर सकते हैं।

संक्षेप में, उन कॉल को अवरुद्ध करने से बचें जिन्हें आप रद्द नहीं कर सकते हैं।

यदि आप नहीं कर सकते हैं और आप ब्लॉकिंग सॉकेट कॉल में आईओ कर रहे हैं तो आप हमेशा थ्रेड से सॉकेट बंद कर सकते हैं, जिसने फैसला किया है कि यह बंद करने का समय है और थ्रेड जो IO कर रहा है पुनः प्रयास करने से पहले 'शटडाउन अब' घटना ...

0

मुझे एक बार एक ही समस्या थी, हालांकि विजुअल बेसिक 6 में: एक ऐप से थ्रेड अलग-अलग सर्वर से कनेक्ट होंगे, कुछ डेटा डाउनलोड करेंगे, उस डेटा पर कुछ ऑपरेशन लूपिंग करेंगे, और परिणामस्वरूप केंद्रीकृत सर्वर पर स्टोर करेंगे।

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

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

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

बहु-थ्रेडिंग के वीबी के "अपार्टमेंट" मॉडल के साथ धागे से मुख्य ऐप में जानकारी भेजने में कुछ मुश्किल है, इसे "आग और भूलना" या इसे केवल मुख्य ऐप से भेजने के लिए बहुत आसान है सूत्र। इस प्रकार, इस तरह के लंबे कटौती की जरूरत है। सी ++ का उपयोग करके आप अपने बहु-थ्रेडिंग मॉडल का उपयोग करने के लिए स्वतंत्र हैं, इसलिए ये बाधाएं आपके लिए लागू नहीं हो सकती हैं।

0

जो कुछ भी आप करते हैं, टर्मिनट थ्रेड का उपयोग करें, खासकर ओएस HTTP कॉल में होने वाली किसी भी चीज़ पर। रीबूट होने तक आप संभावित रूप से IE को तोड़ सकते हैं।

अपने सभी आईओ को एसिंक्रोनस या गैर-अवरुद्ध मॉडल में बदलें ताकि वे समाप्ति घटनाओं को देख सकें।

5

मैं एक अपवाद-आधारित तकनीक का उपयोग करता हूं जो कई Win32 अनुप्रयोगों में मेरे लिए बहुत अच्छा काम करता है।

धागे को समाप्त करने के लिए, मैं QueueUserAPC() का उपयोग किसी फ़ंक्शन को कॉल करने के लिए करता हूं जो अपवाद फेंकता है। हालांकि, जो अपवाद फेंक दिया गया है वह "अपवाद" प्रकार से नहीं लिया गया है, इसलिए केवल मेरे धागे की रैपर प्रक्रिया द्वारा पकड़ा जाएगा। - जैसे ही यह एक alertable प्रतीक्षा राज्य में प्रवेश करती है, यह एपीसी समारोह चलेगा

  • कोई विशेष कोड अपने सूत्र में जरूरत यह stoppable 'बनाने के लिए:

    इस का लाभ इस प्रकार हैं।

  • सभी विनाशकों को शामिल किया जाता है क्योंकि अपवाद स्टैक को चलाता है, इसलिए आपका धागा साफ से निकलता है।

चीजें आप के लिए देखने की जरूरत है:

  • कुछ भी catch (...) कर अपने अपवाद खाएंगे। उपयोगकर्ता कोड हमेशा catch(const Exception &e) या इसी तरह का उपयोग करना चाहिए!
  • सुनिश्चित करें कि आपका I/O और देरी "सतर्क" तरीके से की जाती है। उदाहरण के लिए, इसका मतलब sleep(N) के बजाय sleepex(N, true) पर कॉल करना है।
  • सीपीयू-बाउंड थ्रेड को कभी-कभी समाप्त होने की जांच करने के लिए sleepex(0,true) पर कॉल करने की आवश्यकता होती है।

आप महत्वपूर्ण अनुभागों के दौरान कार्य समाप्ति को रोकने के लिए अपने कोड के क्षेत्रों को 'सुरक्षित' भी कर सकते हैं।

0

यदि आपको अचानक बंद करने की आवश्यकता है: बस ExitProcess पर कॉल करें - वैसे ही जैसे ही आप WinMain से वापस लौटते हैं। विंडोज़ स्वयं कई कार्यकर्ता धागे बनाता है जिनके पास साफ होने का कोई तरीका नहीं है - उन्हें प्रक्रिया बंद करने से समाप्त कर दिया जाता है।

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

0

आप टर्मिनेट प्रोसेस को कॉल कर सकते हैं - यह किसी को सूचित किए बिना और कुछ भी इंतजार किए बिना तुरंत प्रक्रिया को रोक देगा।

0

*NULL = 0 सबसे तेज़ तरीका है। यदि आप क्रैश नहीं करना चाहते हैं, तो exit() या इसके win32 समकक्ष पर कॉल करें।

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