2015-11-15 9 views
5

मैं डेटा संरचना के लिए एक प्रतिलिपि लिख रहा हूं जिसे दो std::atomic<T> सदस्यों को एक नई वस्तु में कॉपी करने की आवश्यकता है। हालांकि प्रक्रिया को मेरे उपयोग-मामले में परमाणु होना जरूरी नहीं है, लेकिन मैं सबसे सही समाधान संभव करना पसंद करूंगा।प्रतिलिपि बनाने वाले परमाणुओं की प्रतिलिपि बनाने के लिए अनलॉकिंग तरीका

मुझे पता है कि प्रतिलिपि निर्माता को std::atomic<T> के साथ स्पष्ट रूप से हटा दिया गया है ताकि उपयोगकर्ताओं को परमाणु इंटरफ़ेस का उपयोग करने के लिए मजबूर किया जा सके।

परमाणु (कॉन्स परमाणु &) = हटाएं;

क्या मैं वर्तमान में मैं कुछ इस तरह कर रहा हूँ कर रहा हूँ:

SomeObject(const SomeObject& other): 
    _atomic1(other._atomic1.load()),    
    _atomic2(other._atomic2.load()) { 
... 
} 

मैं नहीं मानता कि इस आपरेशन परमाणु है, और न ही मैं जानता हूँ कि बनाने के लिए एक तरह से (ताले बिना) तो है।

क्या इन मूल्यों को परमाणु रूप से कॉपी करने का कोई तरीका है (ताले के बिना)?

+0

यदि आप यही पूछ रहे हैं तो दो यादृच्छिक परमाणु वस्तुओं की परमाणु रूप से प्रतिलिपि बनाने का कोई सामान्य तरीका नहीं है। यदि आपको वास्तव में परमाणु प्रति की आवश्यकता है तो एक म्यूटक्स जोड़ें। –

+3

10 में से 9 बार, इस प्रश्न का उत्तर "आपको ऐसा करने की आवश्यकता नहीं है। आप जो कुछ भी गलत तरीके से कर रहे हैं उसके बारे में जा रहे हैं"। यदि डेटा संरचना किसी प्रकार का संग्रह है, उदाहरण के लिए, तो उसके पास पहले से ही एक सामग्रियों-सुरक्षित तरीके से अपनी सामग्री प्राप्त करने का एक तरीका होगा, और आपको इसका उपयोग करना चाहिए। –

+0

@MattTimmermans यह एक महान बिंदु है, यद्यपि मेरा प्रश्न प्रकृति में अकादमिक है। ** इस प्रश्न के दर्शकों को ध्यान में रखना चाहिए और यदि संभव हो तो विशेषज्ञों द्वारा डिजाइन किए गए प्रकारों का उपयोग करना चाहिए। ** Concurrency कठिन है, इसलिए यदि आप कुछ लिखते हैं तो इसे सहकर्मी की समीक्षा करें। –

उत्तर

4

एकमात्र तरीका एक छोटी प्रतिलिपि बनाने योग्य संरचना S बनाने के लिए दो T एस और std::atomic<S> का उपयोग करें।

ध्यान दें कि यह केवल तभी काम करता है जब आप शुरुआत से S का उपयोग कर रहे हैं - ताले के बिना दो अलग परमाणुओं को परमाणु रूप से लोड करने का कोई तरीका नहीं है।

तो बजाय:

struct SomeObject { 
    SomeObject(const SomeObject& other) : i(other.i.load()), j(other.j.load()) { } 
    std::atomic<int> i, j; 
}; 

यह करें:

struct SomeObject { 
    SomeObject(const SomeObject& other) : data(other.data.load()) { } 
    struct Data { int i, j; }; 
    std::atomic<Data> data; 
}; 

ध्यान दें कि यह (शायद होगा) अभी भी ताले आंतरिक रूप से उपयोग कर सकते हैं। यह जांचने के लिए is_lock_free का उपयोग करें।

+0

हम्म। यह रचनात्मक है, लेकिन मुझे संदेह है कि यह आंतरिक रूप से ताले का उपयोग करता है। मैं इसे आज़माउंगा। –

+0

@ डॉनस्कॉट [<= 64 बिट structs के लिए यह लॉकफ्री लगता है, लेकिन बड़ा नहीं है।] (Http://coliru.stacked-crooked.com/a/e496ba55f9a710a8) – orlp

+0

मेरे पास एक ही परिणाम है, लेकिन दर्शकों को यह ध्यान रखना चाहिए कि ** यह व्यवहार कंपाइलर और आर्किटेक्चर निर्भर है। ** संरेखित 8 बाइट्स पढ़ने/लिखने आमतौर पर हाल ही के हार्डवेयर (32 बिट ऑपरेटिंग सिस्टम पर) पर परमाणु हैं, लेकिन उपयोगकर्ताओं को अपने सिस्टम को सत्यापित करने के लिए सावधानी बरतनी चाहिए। –

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