2012-07-25 11 views
5

स्क्रैच से थ्रेड-सुरक्षित कंटेनर क्लास बनाने का प्रयास करने में, मैंने एक्सेस विधियों से मूल्यों को वापस करने की समस्या में भाग लिया है। Windows में उदाहरण के लिए:क्रिटिकल सेक्शन और सी ++

myNode getSomeData() 
{ 
    EnterCriticalSection(& myCritSec); 
    myNode retobj; 
    // fill retobj with data from structure 
    LeaveCriticalSection(& myCritSec); 
    return retobj; 
} 

अब मुझे लगता है कि विधि के इस प्रकार पर नहीं है सभी धागे की सुरक्षित क्योंकि के बाद कोड महत्वपूर्ण अनुभाग एक और धागा आकर तुरंत पहले धागा से पहले retobj अधिलेखित करने में सक्षम है विज्ञप्ति रिटर्न। तो retobj को कॉलर को थ्रेड-सुरक्षित तरीके से वापस करने का एक शानदार तरीका क्या है?

+1

लेकिन retobj ढेर पर संग्रहीत है? जब तक इसे 'स्थैतिक' घोषित नहीं किया जाता है, तब तक आपको प्रतिलिपि किए गए डेटा को ओवरराइट करने में कोई समस्या नहीं होनी चाहिए। –

+0

जब तक कि कुछ अजीब नहीं हो रहा है, 'retobj' ढेर पर होना चाहिए, और प्रत्येक धागे का अपना ढेर होना चाहिए। जब आप प्री-आवंटित मेमोरी के साथ काम कर रहे हों तो इस प्रकार की रेस की स्थिति अधिक आम होती है और साझाकरण को रोकने के लिए एक्सेस को लॉक करना पड़ता है। – ssube

+0

@inface, ठीक है, ठीक है, इसलिए जब तक स्टैक पर वापसी मूल्य संग्रहीत किया जाता है, मैं अच्छा हूं। – ThomasMcLeod

उत्तर

7

नहीं, यह थ्रेड-सुरक्षित है क्योंकि प्रत्येक धागे का अपना ढेर होता है, और वह है जहां retobj है।

हालांकि, यह निश्चित रूप से अपवाद-सुरक्षित नहीं है। एक RAII- शैली वस्तु में महत्वपूर्ण खंड लपेटें इससे मदद मिलेगी। कुछ की तरह ...

class CriticalLock : boost::noncopyable { 
    CriticalSection &section; 

public: 
    CriticalLock(CriticalSection &cs) : section(cs) 
    { 
    EnterCriticalSection(section); 
    } 

    ~CriticalLock() 
    { 
    LeaveCriticalSection(section); 
    } 
}; 

उपयोग:

myNode getSomeData() 
{ 
    CriticalLock lock(myCritSec); // automatically released. 
    ... 
} 
2

यह सी ++ है, और retobj में स्वचालित संग्रहण प्रकार है, इसलिए यह ढेर पर संग्रहीत है।

प्रत्येक धागे का अपना ढेर होता है, इसलिए दूसरा धागा वापस आने से पहले retobj के मान को रोक नहीं सकता है।

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