2012-10-27 13 views
11

जैसा कि http://en.cppreference.com/w/cpp/error/terminate में बताया गया है, समाप्त करने के कई कारण हैं। मैं ऐसे मामले की कल्पना कर सकता हूं जहां लगभग एक ही समय में इनमें से कुछ कारण दो धागे में होते हैं।उपयोगकर्ता को प्रदान किया जाना चाहिए() फ़ंक्शन थ्रेड-सुरक्षित होना चाहिए?

Q1std::set_terminate द्वारा निर्धारित समाप्त समारोह एक ही समय में दो बार या उससे अधिक कहा जा सकता है, एक ही समय से मैं पहली बार समाप्त हो गया है इससे पहले कि दूसरी कॉल शुरू होता है मतलब है।

Thread1 Thread2 
    |   | 
    _   | 
    t   | 
    e   | 
    r   | 
    m   | 
    i   _ 
    n   t 
    a   e 
    t   r 
    e   m 
    -   ? 

Q2 तो Q1 == हाँ, तो क्या होता पहले समाप्त हो गया समाप्त कर। मुझे लगता है कि अगर यह std :: abort के साथ समाप्त होता है, तो प्रोग्राम समाप्त होता है, लेकिन क्या होता है यदि उपयोगकर्ता द्वारा प्रदान किया गया प्रोग्राम प्रोग्राम को रोक नहीं देता है?

Q3 क्या std::set_terminate द्वारा निर्धारित टर्मिनल फ़ंक्शन थ्रेड के संदर्भ में बुलाया गया है जिसके कारण यह समाप्ति कॉल हुई?

उत्तर

7

Q1

हाँ, std::terminate समवर्ती कहा जा सकता है।

Q2

मानक यह अपरिभाषित व्यवहार है एक terminate_handler के लिए नहीं "फोन करने वाले की ओर लौटने के बिना कार्यक्रम के निष्पादन समाप्त" के लिए कहते हैं। कार्यान्वयन में मैं परिचित हूं, अगर terminate_handler लौटने का प्रयास करता है, या तो सामान्य रूप से, या असाधारण रूप से, abort() कहा जाएगा।

Q3

समारोह std::terminate द्वारा निर्धारित एक वैश्विक, एक धागा नहीं स्थानीय है। तो एक धागा दूसरे को प्रभावित कर सकता है।

में सी ++ 98/03, terminate_handler न आया हुआ अपवाद के कारण जब terminate कहा जाता है प्रयोग किया जाता है कि प्रभाव में था जब अपवाद उत्पन्न हुआ था, प्रभाव में नहीं एक जब terminate वास्तव में कहा जाता है (हालांकि वे आमतौर पर वही होते हैं)।

सी ++ में 11 यह बदल गया था और मानक अब कहता है कि terminate पर इस्तेमाल किया जाने वाला हैंडलर एक जगह है। यह परिवर्तन गलती से किया गया था और भविष्य में मसौदे में सबसे अधिक सुधार किया जाएगा। यहाँ LWG इस मुद्दे को इस समस्या को ट्रैक:

http://cplusplus.github.com/LWG/lwg-active.html#2111

अद्यतन

Lenexa, के एस में 2015 के वसंत बैठक में LWG मौजूदा व्यवहार का मानकीकरण करने का फैसला किया है और यह अनिर्दिष्ट बना जब एक नया terminate_handler प्रभाव में चला जाता है अगर set_terminate स्टैक अनचाहे के दौरान बुलाया जाता है। अर्थात। कार्यान्वयन को सी ++ 98/03 नियम या सी ++ 11 नियमों का पालन करने की अनुमति है।

अपना कोड पोर्टेबल बनाने के लिए, यदि आपको terminate_handler सेट करने की आवश्यकता है, तो प्रोग्राम अप स्टार्टअप के दौरान ऐसा करें, किसी अपवाद को फेंकने से पहले, और इसके बाद set_terminate पर कॉल करने की आदत न बनाएं।

+0

+1।विषय में प्रश्न का उत्तर देने के लिए: उपयोगकर्ता प्रदान किए गए कार्य को थ्रेड सुरक्षित होना चाहिए? अन्य "आपदा" कार्यों के बारे में क्या? New_handler के बारे में क्या? क्या यह जीसीसी सलाह डबल डिलीट होने के खतरनाक है: http://gcc.gnu.org/onlinedocs/libstdc++/manual/dynamic_memory.html? – PiotrNycz

+0

चूंकि 'std :: terminate' को समवर्ती रूप से कहा जा सकता है, इसलिए 'terminate_handler' थ्रेड सुरक्षित होना चाहिए। और मानक में निर्दिष्ट सभी अन्य हैंडलरों के बारे में भी यही सच है, जिसमें 'new_handler' शामिल है। हां, जीसीसी उदाहरण डबल डिलीट करने के खतरे में है। इसे 'सुरक्षा' पर परमाणु विनिमय के साथ हल किया जा सकता है। –

+0

"std :: set_terminate द्वारा सेट फ़ंक्शन एक वैश्विक है" - क्यों? कुछ कार्यान्वयन कहते हैं कि यह स्थानीय है ([एमएस: समाप्ति कार्यों को प्रत्येक थ्रेड के लिए अलग से बनाए रखा जाता है] (http://msdn.microsoft.com/en-us/library/aa272914 (v = vs.60) .aspx); [ibm : आप इसे थ्रेड-स्तरीय समाप्ति के साथ ओवरराइड कर सकते हैं] (http://publib.boulder.ibm.com/infocenter/zos/v1r11/index.jsp?topic=/com.ibm.zos.r11.bpxbd00/setterm। एचटीएम); [सूर्य: धागा अपना सेट कर सकता है] (http://www.amath.unc.edu/sysadmin/DOC4.0/c-plusplus/c%2B%2B_ug/Exception_Handling.doc.html)) ' मानक में सटीक परिभाषा नहीं मिलती है। http://stackoverflow.com/q/15367060/196561 – osgx

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