2009-08-26 14 views
9

वर्ग विशिष्ट new_handler कार्यान्वयन के लिए, मैं निम्नलिखित उदाहरणों में "प्रभावी सी ++" पुस्तक में आया हूं। यह बहुप्रचारित वातावरण में समस्या दिखता है, मेरा प्रश्न यह है कि बहु विशिष्ट वातावरण में वर्ग विशिष्ट new_handler को कैसे प्राप्त किया जाए?वर्ग विशिष्ट set_new_handler

void * X::operator new(size_t size) 
{ 
    new_handler globalHandler =    // install X's 
    std::set_new_handler(currentHandler); // handler 
    void *memory; 
    try {          // attempt 
     memory = ::operator new(size);   // allocation 
    } 
    catch (std::bad_alloc&) {     // restore 
     std::set_new_handler(globalHandler);  // handler; 
     throw;         // propagate 
    }           // exception 
    std::set_new_handler(globalHandler);  // restore 
               // handler 
    return memory; 
} 

उत्तर

4

आप सही हैं। यह शायद धागा सुरक्षित नहीं है। इसके बजाय आप nothrow version of new का उपयोग कर की तरह एक वैकल्पिक दृष्टिकोण पर विचार करना चाहते हो सकता है:

void* X::operator new(std::size_t sz) { 
    void *p; 
    while ((p = ::operator new(sz, std::nothrow) == NULL) { 
    X::new_handler(); 
    } 
    return p; 
} 

इस कारण होगा जब भी स्मृति आवंटन में विफल रहता है अपने वर्ग-विशेष हैंडलर कहा जाता है। मैं तब तक ऐसा नहीं करूँगा जब तक आप operator new ओवरलोडिंग के आसपास के सभी सिरदर्दों को वास्तव में समझ नहीं पाते। विशेष रूप से, हर्ब सटर के दो भाग लेख को नया, पर्चेंस टू थ्रो, Part 1 और Part 2 पढ़ें। दिलचस्प है, वह nothrow संस्करण से बचने के लिए कहता है ... हमम।

0

सी ++ (अभी तक) पता नहीं है कि धागे क्या हैं। ऐसा करने के लिए आपको थ्रेड सुरक्षित तरीका निर्धारित करने के लिए, या यदि यह भी संभव हो, तो आपको अपने कंपाइलर/सी ++ मानक लाइब्रेरी/ऑपरेटिंग सिस्टम/थ्रेड लाइब्रेरी मैनुअल पर जाना होगा। मैं सुझाव दूंगा कि नया हैंडलर शायद पूरे एप्लिकेशन में समान होना चाहिए। यह एक बहुत ही लचीला तंत्र नहीं है, शायद आपकी जरूरतों को एक आवंटक या शायद एक कारखाने (समारोह) के साथ बेहतर सेवा दी जाएगी? आप कस्टम नए हैंडलर के अंदर क्या करना चाहते हैं?

0

शायद आप इसे गलत तरीके से देख रहे हैं। मुझे नहीं लगता कि पूरे एप्लिकेशन को स्मृति आवंटित करने से सीमित करने का कोई तरीका है (क्योंकि स्मृति आवंटन में से अधिकांश आपके कोड के बाहर हो सकते हैं), इसलिए ऐसा करने का सबसे अच्छा तरीका यह है कि आप क्या कर सकते हैं - यानी कार्यान्वयन हैंडलर का।

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

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

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