2012-08-31 17 views
13

मैं निम्नलिखित कोड पैटर्न है:साझा मेमोरी (सी ++) में एसटीएल ऑब्जेक्ट्स को कैसे स्टोर करें?

class A { 
    double a, b, c; 
    ... 
}; 

class B { 
    map<int, A> table; // Can have maximum of MAX_ROWS elements. 
    ... 
}; 

class C { 
    B entries; 
    queue<int> d; 
    queue<int> e; 
    ... 
}; 

अब मैं, एक साझा स्मृति में टाइप सी की एक वस्तु स्टोर करने के लिए इतना है कि विभिन्न प्रक्रियाओं जोड़ सकते हैं, अद्यतन और इसे पढ़ने चाहते हैं। मैं यह कैसे कर सकता हूँ? (नोट: मुझे पता है कि एक साधारण सी सरणी साझा स्मृति में एक निश्चित आकार है कि स्टोर करने के लिए यह भी ध्यान रखें B.table मनमाना प्रविष्टियों हो सकता है

+1

यह आसान नहीं है। आपको अपने सभी कंटेनर के लिए एक विशेष आवंटक की आवश्यकता होगी जो साझा स्मृति के बारे में जानता है। सी ++ 11 में यह राज्य के आवंटकों को धन्यवाद लागू करने के लिए थोड़ा आसान है, लेकिन यह किसी भी घटना में गैर-तुच्छ है। –

+1

कौन सा मंच? – tenfour

+0

यह मंच-निर्भर है। – someguy

उत्तर

17

उपयोग boost::interprocess, इस पुस्तकालय इस कार्यक्षमता को उजागर करता है

।।। संपादित करें: यहाँ कुछ परिवर्तन तुम क्या करने की आवश्यकता होगी:।

उदाहरण पहले से ही एक संभाजक कि साझा स्मृति ब्लॉक से आवंटित करेगा परिभाषित करता है, तो आप map और queue को यह पारित करने के लिए की जरूरत है इसका मतलब है आप होगा अपनी परिभाषाओं को बदलने के लिए:

class B 
{ 
    map<int, A, less<int>, MapShmemAllocator> table; 

    // Constructor of the map needs the instance of the allocator 
    B(MapShmemAllocator& alloc) : table(less<int>(), alloc) 
    { } 
} 

queue के लिए, इस वजह से तथ्य यह है कि यह वास्तव में सिर्फ एक एडाप्टर है की थोड़ा जटिल है, है, तो आप एक टेम्पलेट पैरामीटर के रूप में वास्तविक कार्यान्वयन कक्षा में पारित करने के लिए की जरूरत है:

typedef queue<int, deque<int, QueueShmemAllocator> > QueueType; 

अब आप अपने वर्ग C परिवर्तनों में कुछ :

class C 
{ 
    B entries; 
    QueueType d, e; 

    C(MapShmemAllocator& allocM, QueueShmemAllocator& allocQ) : entries(allocM), d(allocQ), e(allocQ) 
    { } 
} 

अब खंड प्रबंधक से, C का एक उदाहरण संभाजक साथ निर्माण।

C *pC = segment.construct<C>("CInst")(allocM_inst, allocQ_inst); 

मुझे लगता है कि यह चाल चलनी चाहिए। नोट: आपको दो आवंटकों (queue और map के लिए एक) प्रदान करने की आवश्यकता होगी, सुनिश्चित नहीं है कि आप एक ही सेगमेंट मैनेजर से दो आवंटकों का निर्माण कर सकते हैं, लेकिन मुझे नहीं लगता कि क्यों नहीं।

+0

मैंने इसे पहले देखा था। मैंने पहले कभी इसका इस्तेमाल नहीं किया है, इसलिए थोड़ा संकोच था। क्या आप कृपया मेरी आवश्यकताओं को पूरा करने के लिए नीचे दिए गए लिंक पर कोड को अनुकूलित करने के तरीके पर एक अजीब विचार दे सकते हैं। http://www.boost.org/doc/libs/1_37_0/doc/html/interprocess/quick_guide.html#interprocess.quick_guide.qg_interprocess_map – shobhu

+0

@shobhu, उदाहरण में कुछ बदलावों के साथ अपडेट किया गया है जो काम करना चाहिए ... – Nim

2

यह मुश्किल हो सकता है। स्टार्टर्स के लिए, आपको कस्टम आवंटन की आवश्यकता होगी: बूस्ट इंटरप्रोसेस में एक है, और मैं इसके साथ शुरू करूंगा। आपके सटीक उदाहरण में, यह पर्याप्त हो सकता है, लेकिन अधिक आम तौर पर, आपको यह सुनिश्चित करना होगा कि सभी उपप्रकार भी साझा स्मृति का उपयोग करते हैं। इस प्रकार, यदि आप से एक स्ट्रिंग को मैप करना चाहते हैं, तो उस स्ट्रिंग को कस्टम आवंटन की भी आवश्यकता होगी, जिसका अर्थ है कि इसका std::string से भिन्न प्रकार है, और आप कॉपी नहीं कर सकते हैं या इसे std::string से असाइन नहीं कर सकते हैं (लेकिन आप की तरह पहुंच के साथ

typedef std::basic_string<char, std::char_traits<char>, ShmemAllocator> ShmemString; 
std::map<ShmemString, X, std::less<ShmemString>, ShmemAllocator> shmemMap; 

: दो इटरेटर निर्माता, जैसे उपयोग कर सकते हैं

shmemMap[ShmemString(key.begin(), key.end())] ... 

और निश्चित रूप से, किसी भी प्रकार आप को परिभाषित जो नक्शे में जाने को भी किसी भी आवंटन के लिए साझा स्मृति का उपयोग करना चाहिए एस: बूस्ट इंटरप्रोसेस में offset_ptr है जो यहां सहायता कर सकता है।

1

साझा स्मृति में एसटीएल ऑब्जेक्ट्स का निर्माण और उपयोग करना अभी तक मुश्किल नहीं है (विशेष रूप से बूस्ट :: इंटरप्रोसेस रैपर का उपयोग करना)। निश्चित रूप से आपको सिंकिंग तंत्र का भी उपयोग करना चाहिए (बूस्ट के नाम_म्यूटेक्स के साथ कोई समस्या नहीं है)।

वास्तविक चुनौती एक साझा स्मृति में एसटीएल वस्तुओं की स्थिरता बनाए रखना है। मूल रूप से, अगर प्रक्रियाओं में से एक समय में एक बुरी बात में दुर्घटनाओं, यह अन्य प्रक्रियाओं एक दो बड़ी समस्याओं के साथ छोड़ देता है:

  • एक म्युटेक्स बंद कर दिया (मुश्किल पीआईडी ​​करने वाली म्युटेक्स मैपिंग, मजबूत mutexes का उपयोग कर हल किया जा सकता (जहां भी उपलब्ध हो), टाइम म्यूटेक्स इत्यादि

  • असंगत स्थिति में एक एसटीएल ऑब्जेक्ट (उदाहरण के लिए मिट-अपडेटेड मानचित्र संरचना मिटाने() प्रक्रिया के दौरान)। आम तौर पर, यह अभी भी पुनर्प्राप्त करने योग्य नहीं है, आपको नष्ट करने और फिर से स्क्रैच से साझा किए गए मेमोरी क्षेत्र में ऑब्जेक्ट का निर्माण करें (शायद अन्य सभी प्रक्रियाओं को भी मारना)। आप अपने ऐप में सभी संभावित बाहरी सिग्नल को रोकने और उंगलियों को पार करने की कोशिश कर सकते हैं उम्मीद है कि सब कुछ ठीक हो जाएगा और प्रोसेस एक बुरे पल में कभी असफल नहीं होता है।

बस अपने सिस्टम में साझा स्मृति का उपयोग करने का निर्णय लेने पर इसे ध्यान में रखें।