2013-05-23 6 views
7

मैं सोच रहा था, क्या केवल प्राचीन डेटा प्रकारों को सी ++ 11 में std :: atomic घोषित किया जा सकता है? क्या लाइब्रेरी क्लास ऑब्जेक्ट को "परमाणु रूप से" उत्परिवर्तित या एक्सेस करने के लिए घोषित करना संभव है?सी ++ 11 केवल आदिम डेटा प्रकार परमाणु घोषित किया जा सकता है?

उदाहरण के लिए, मैं

using namespace std::chrono; 
time_point<high_resolution_clock> foo; 

// setter method 
void set_foo() { 
    foo = high_resolution_clock::now(); 
} 

// getter method 
time_point<high_resolution_clock> get_foo() { 
    return foo; 
} 

है लेकिन, हो सकता है इन सेटर और गेटर तरीकों अलग धागे में कहा जाता है, तो मुझे लगता है कि अपरिभाषित व्यवहार हो सकता है। यह अच्छा होगा अगर मैं की तरह foo कुछ की घोषणा सकता है:

std::atomic<time_point<high_resolution_clock>> foo; 

... ताकि foo पर सभी कार्यों एक परमाणु फैशन में आयोजित की जाएगी। मेरे प्रोजेक्ट के लिए आवेदन में संभवतः सैकड़ों ऐसे फू वेरिएबल्स दर्जनों कक्षाओं में घोषित किए गए हैं, और मुझे लगता है कि ऑब्जेक्ट को म्यूटेट करने और "परमाणु" तक पहुंचने के लिए यह कहने के लिए कहीं अधिक सुविधाजनक होगा, बजाय घोषणा करने और लॉक_गार्ड पूरे स्थान पर mutexes।

क्या यह संभव नहीं है, या कोई बेहतर दृष्टिकोण है, या क्या मुझे वास्तव में हर जगह एक म्यूटेक्स और लॉक_गार्ड का उपयोग करना है?

अद्यतन:

  • कोई खरीदार? मैं सभ्य जानकारी के लिए वेब के चारों ओर मछली पकड़ रहा हूं, लेकिन परमाणु का उपयोग करके बहुत कम उदाहरण हैं कि मैं यह सुनिश्चित नहीं कर सकता कि इसे किस हद तक लागू किया जा सकता है।
+0

std :: atomic टूटा हुआ कोड के लिए कोई कामकाज नहीं है। यदि कोई अन्य धागा सेटटर को कॉल करता है तो जो भी पहले थ्रेड कहलाता है उसे वैसे भी गेटर से कचरा मूल्य मिल जाएगा। –

उत्तर

3

atomic<> आदिम प्रकार तक ही सीमित नहीं है। इसे atomic<> का उपयोग T के साथ trivially copyable पर करने की अनुमति है। अनुभाग से 29.5 परमाणु प्रकार C++ 11 मानक के (यह भी std::atomic में कहा गया है):

एक सामान्य वर्ग टेम्पलेट परमाणु नहीं है। टेम्पलेट तर्क टी का प्रकार तुच्छ रूप से कॉपी करने योग्य (3.9) होगा।

हैं वस्तुओं जिसके लिए परमाणु पहुंच आवश्यक है atomic<> के साथ उपयोग नहीं किया जा सकता है तो, नई वस्तुओं को परिभाषित मूल वस्तु और एक std::mutex हैं। इसका मतलब है कि lock_guard<> का उपयोग केवल नए थ्रेड सुरक्षित ऑब्जेक्ट के गेटर और सेटर के भीतर किया जाता है, और पूरे कोड में बिखरा नहीं जाता है। एक template धागा सुरक्षा मशीनरी की आवश्यकता परिभाषित करने में सक्षम हो सकता है:

template <typename T> 
class mutable_object 
{ 
public: 
    mutable_object() : t_() {} 
    explicit mutable_object(T a_t) : t_(std::move(a_t)) {} 
    T get() const 
    { 
     std::lock_guard<std::mutex> lk(mtx_); 
     return t_; 
    } 
    void set(T const& a_t) 
    { 
     std::lock_guard<std::mutex> lk(mtx_); 
     t_ = a_t; 
    } 
private: 
    T t_; 
    mutable std::mutex mtx_; 
}; 

using mutable_high_resolution_clock = 
     mutable_object<std::chrono::time_point< 
      std::chrono::high_resolution_clock>>; 

using mutable_string = mutable_object<std::string>; 

mutable_high_resolution_clock c; 
c.set(std::chrono::high_resolution_clock::now()); 
auto c1 = c.get(); 

mutable_string s; 
s.set(std::string("hello")); 
auto s1 = s.get(); 
0

एटोमिक्स तक ही सीमित तुच्छता copyable वर्गों (अर्थात वर्ग है जो किसी भी कस्टम प्रतिलिपि निर्माता है, और जिसके सदस्य भी तुच्छता copyable हैं)।

इस आवश्यकता को एटोमिक्स के लिए बहुत बड़ा लाभ हैं: क्योंकि एक निर्माता फेंक दिया

  • सभी एटोमिक्स एक ताला (spinlock या म्युटेक्स) और डेटा की प्रतिलिपि memcpy के साथ तैयार किया जा सकता है

    • कोई परमाणु आपरेशन फेंक कर सकते हैं।
    • सभी परमाणुओं के पास एक सीमित रन टाइम (बाध्य) होता है।

    उत्तरार्द्ध के रूप में एटोमिक्स कभी कभी spinlocks का उपयोग करके लागू विशेष रूप से उपयोगी है, है, और यह अत्यधिक एक spinlock दबाते हुए असीम कार्यों से बचने के लिए वांछित है। यदि किसी भी निर्माता को अनुमति दी गई थी, तो कार्यान्वयन को पूर्ण उड़ाए गए म्यूटेक्स पर वापस गिरने की आवश्यकता होगी, जो बहुत छोटे महत्वपूर्ण वर्गों के लिए स्पिनलॉक्स से धीमे होते हैं।

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