2009-06-09 6 views
6

क्या यह एक्स्टिट फ़ंक्शन के माध्यम से WSACleanup को पंजीकृत करना ठीक है? हमारे पास कई एप्लिकेशन हैं जो कोड में अलग-अलग बिंदुओं पर समाप्त हो सकते हैं ताकि हम हर जगह WSACleanup को कोड के माध्यम से डालने से बचाना चाहें। निश्चित रूप से हम डब्लूएसएएसएर्टनअप/डब्ल्यूएसएसीलेनअप को डेलमेन के माध्यम से कॉल करते हैं क्योंकि हमारे पास इन सभी अनुप्रयोगों द्वारा उपयोग किया जाने वाला एक डीएलएल है। हालांकि, माइक्रोसॉफ्ट डब्लूएसएएसएर्ट के माध्यम से डब्लूएसएएसएर्टर्टअप/डब्ल्यूएसएसीलेनअप के उपयोग के खिलाफ सख्ती से सलाह देता है क्योंकि इससे डेडलॉक्स हो सकते हैं। हम WSAStarup को DllMain से बाहर ले जा सकते हैं और विंडोज सॉकेट लाइब्रेरी तक पहुंचने से पहले सभी अनुप्रयोगों के लिए कोड में एक बिंदु पर इसे कॉल कर सकते हैं। और, जैसे ही हम WSAStartup को कॉल करते हैं, हम WSACleanup पर कॉल पंजीकृत करने के लिए atExit फ़ंक्शन का उपयोग करना चाहते हैं। क्या किसी के पास इस दृष्टिकोण के साथ कोई अनुभव है? धन्यवाद!WSACleanup और atExit

उत्तर

4

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

1

ठीक है मुझे लगता है कि एक्साइट का उपयोग नहीं किया जाना चाहिए। आपको कक्षा में सॉकेट लाइब्रेरी के प्रारंभिकरण और विनाश के रैपिंग के आरएआईआई सिद्धांत का पालन करना चाहिए।

+0

जबकि अच्छा शैली, इस एक कण मदद नहीं करता है। एक प्रक्रिया दृष्टिकोण से, atexit() प्रसंस्करण वैश्विक विनाशकर्ता के संचालन के रूप में एक ही समय में होता है। किसी भी मुद्दे आप atexit से WSACleanup बुला के साथ होगा, आप की संभावना अभी भी एक dtor से बुला whan होगा। – MSalters

2

मैं मानता हूं कि आरएआईआई दृष्टिकोण अनुकूल है।

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

आदेश है कि atexit संचालकों खिड़कियों पर कहा जाता है:

  1. कहीं बाहर निकलने कहा जाता है या मुख्य है() गुंजाइश
  2. atexit प्रक्रिया में परिभाषित हैंडलर कहलाते हैं से बाहर चला जाता है।
  3. सभी हैंडल नष्ट हो गए हैं।
  4. डीएलएस में परिभाषित अतुलनीय हैंडलर को बुलाया जाता है।

इससे कोई फर्क नहीं पड़ता अगर DLLs में atexit संचालकों प्रक्रिया में संचालकों से पहले पंजीकृत हैं प्रक्रिया संचालकों पहले कहा जाता है और हैंडल dll हैंडलर कहलाते हैं से पहले नष्ट कर रहे हैं। इसका परिणाम Win32 अपवादों में होता है, जब क्लीन अप कोड को डीएलएस के स्वामित्व वाले सभी हैंडल के रूप में बुलाया जाता है, अब मान्य नहीं होते हैं।

यह प्रभाव कोड जो थ्रेड, म्यूटेक्स, फाइल, सॉकेट आदि को संभालता है। यदि उन्हें एक डीएल में आवंटित किया जाता है तो उन्हें बाहर निकलने से पहले साफ किया जाना चाहिए या नहीं।

वैसे मैं विरोधी खिड़की नहीं कर रहा हूँ, अगर मैं गलत हूँ या किसी को भी इस के आसपास किसी भी तरह से मुझे पता है के रूप में यह मेरे अनकही दर्द आवेदन में साफ का कारण बनता है प्यार होता है जानता है। अनुप्रयोगों से बाहर निकलने पर Win32 अपवाद प्राप्त करने के बाद, मुझे यह पता चला कि सी ++ रनटाइम में बाहर निकलने के लिए बाहर निकलना है।

मुझे अपने कोड से बाहर निकलने के लिए सभी कॉल को हटाना पड़ा। अब मैंने सुनिश्चित किया है कि एक डीएल में कोई स्थिर डेटा एक हैंडल को नियंत्रित नहीं करता है। सभी स्थैतिक हैंडल उन वस्तुओं द्वारा नियंत्रित होते हैं जो मुख्य रूप से दायरे से बाहर होने पर नष्ट हो जाते हैं।

+1

टूटा नहीं। आप EXE से वैश्विक dtors से पहले DLLs उतार दिया है, तो अनुप्रयोग से किसी भी dtor असफल जब कि dtor से एक समारोह बुला होगा।वर्तमान सेटअप EXE को डीएलएल पर निर्भर करता है, लेकिन दूसरी तरफ नहीं। इसके अलावा, आपको DLLMain में हैंडल को खोलना या बंद नहीं करना चाहिए, यह एक नया नियम नहीं है। AtExit प्रसंस्करण DLLMain का हिस्सा है, इसलिए यह उन नियमों को प्राप्त करता है। सभी डीएलएल संसाधनों के लिए स्मार्ट पॉइंटर्स का उपयोग करने का एक त्वरित समाधान है। जब एप्लिकेशन डीएलएल संसाधन के लिए अपने अंतिम स्मार्ट सूचक को साफ़ करता है, तो डीएलएल को पता चलेगा कि यह साफ हो सकता है, और यह एटएक्सिट से पहले है। – MSalters

+0

DLLMain पर नोट के लिए धन्यवाद, मुझे यह एहसास नहीं हुआ। स्मार्ट पॉइंटर पर आपका नोट: यह केवल तभी काम करेगा जब इसे मुख्य या नीचे घोषित किया गया हो और स्थिर नहीं है, है ना? – iain

+0

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

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