2010-12-22 7 views
13

में धागे विनाशक इन दिनों मैं पीडीएफ Designing MT programs पढ़ रहा हूं। यह बताता है कि उस ऑब्जेक्ट को दायरे से बाहर होने से पहले उपयोगकर्ता को std::thread कक्षाकी किसी ऑब्जेक्ट पर स्पष्ट रूप से detach() पर कॉल करना होगा। यदि आप इसे std::terminate() नहीं कहते हैं तो कॉल किया जाएगा और एप्लिकेशन मर जाएगा।सी ++ 0x बनाम बूस्ट

मैं आमतौर पर सी ++ में थ्रेडिंग के लिए boost::thread का उपयोग करता हूं। अगर मैं गलत हूं तो मुझे सही करें लेकिन boost::thread ऑब्जेक्ट स्कोप से बाहर होने पर स्वचालित रूप से अलग हो जाता है।

मुझे लगता है कि बढ़ावा दृष्टिकोण एक आरएआईआई सिद्धांत का पालन करता है और std नहीं करता है।

क्या आप जानते हैं कि इसके लिए कोई विशेष कारण है?

उत्तर

16

यह वास्तव में सच है, और यह पसंद std::thread नाशक के बारे में एक नोट पर N3225 समझाया गया है:

तो joinable()terminate(), अन्यथा कोई प्रभाव। [नोट: या तो परोक्ष अलग करने या का सामना करना पड़ा एक अपवाद उठाया है केवल तभी जब इसकी नाशक में एक joinable() धागा में शामिल होने के लिए मुश्किल डिबग शुद्धता (अलग) या प्रदर्शन करने में परिणाम सकता है कीड़े (में शामिल होने के लिए)। इस प्रकार प्रोग्रामर को यह सुनिश्चित करना चाहिए कि विनाशक कभी भी निष्पादित नहीं होता है जबकि थ्रेड अभी भी जुड़ने योग्य है। अंत टिप्पणी]

जाहिर समिति दो बुराइयों से कम के लिए चला गया।


संपादित मैं सिर्फ this interesting paper पाया जो बताता है कि क्यों प्रारंभिक शब्दों:

तो joinable() तो detach(), अन्यथा कोई प्रभाव।

पहले उद्धृत एक के लिए बदला गया था।

+1

कन्स्ट्रक्टर में join_on_destruction या detach_on_destruction ध्वज क्यों नहीं है, या स्पष्ट रूप से इसके व्यवहार को निर्दिष्ट करने का कोई अन्य तरीका नहीं है। – Puppy

+0

एक दिलचस्प पेपर है [यहां] (http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2008/n2802.html) – icecrime

+1

हाय IceCrime। कागज के लिए धन्यवाद। इसलिए मूल रूप से प्रलोभन को मारना threads..in दिलचस्प और वास्तव में 'रक्षात्मक' तरीके से त्रुटियों के बारे में झंडा बढ़ाने का सबसे स्पष्ट तरीका है। :) –

3

यहां RAII धागे को लागू करने का एक तरीका है।

#include <memory> 
#include <thread> 

void run() { /* thread runs here */ } 

struct ThreadGuard 
{ 
    operator()(std::thread* thread) const 
    { 
     if (thread->joinable()) 
      thread->join(); // this is safe, but it blocks when scoped_thread goes out of scope 
     //thread->detach(); // this is unsafe, check twice you know what you are doing 
     delete thread; 
    } 
} 

auto scoped_thread = std::unique_ptr<std::thread, ThreadGuard>(new std::thread(&run), ThreadGuard()); 

आप इस का उपयोग करने, read this first एक धागा अलग करना चाहते हैं।