2011-10-19 13 views
44

विशेष रूप से, मैं एक अवरुद्ध कतार की तलाश में हूं। क्या सी ++ 11 में ऐसी कोई चीज है? यदि नहीं, तो मेरे अन्य विकल्प क्या हैं? मैं वास्तव में अब थ्रेड स्तर पर जाना नहीं चाहता हूं। रास्ता भी त्रुटि-प्रवण।क्या सी ++ 11 में कोई समवर्ती कंटेनर हैं?

+2

+1, दिलचस्प Q.Scott मेयर्स ने इसे सी ++ 0x दिनों [यहां] (http://www.velocityreviews.com/forums/t732306-concurrent-containers.html) में पूछा। यह जानना दिलचस्प होगा सी ++ 11 के बाद यह कैसे बदल गया है। –

+0

प्राइमेटिव –

उत्तर

32

According to Diego Dagum from Microsoft's Visual C++ Team:

एक आवर्तक सवाल (अच्छी तरह से, कई में से एक) एसटीएल कंटेनर के बारे में है और क्या वे सुरक्षित धागा है। हर एसटीएल कंटेनर एक आंतरिक ताला प्राप्त प्रदर्शन का सफाया होगा के हर सदस्य समारोह होने:

यहाँ स्टीफ़न का शब्द ले रहा है, वास्तविकता यह है कि वे एक बग के रूप में नहीं बल्कि एक सुविधा के रूप में, नहीं कर रहे हैं। एक सामान्य उद्देश्य, अत्यधिक पुन: प्रयोज्य लाइब्रेरी, यह वास्तव में सहीता प्रदान नहीं करेगा: लॉक रखने के लिए सही स्तर प्रोग्राम द्वारा किया जा रहा है द्वारा निर्धारित किया गया है। उस अर्थ में, व्यक्तिगत सदस्य फ़ंक्शन ऐसे सही स्तर के रूप में नहीं होते हैं।

  • concurrent_vector Class एक दृश्य कंटेनर वर्ग है कि किसी भी तत्व को रैंडम एक्सेस की अनुमति देता है:

The Parallel Patterns Library (पीपीएल) कई कंटेनरों कि उनके तत्वों के धागे की सुरक्षित पहुँच प्रदान भी शामिल है। यह समवर्ती-सुरक्षित परिशिष्ट, तत्व पहुंच, इटरेटर एक्सेस और इटरेटर ट्रैवर्सल ऑपरेशंस को सक्षम बनाता है।

  • concurrent_queue Class एक अनुक्रम कंटेनर क्लास है जो इसके तत्वों में पहली बार, पहली बार पहुंच की अनुमति देता है। यह कुछ नामों के लिए पुश और try_pop जैसे समवर्ती-सुरक्षित संचालन के सीमित सेट को सक्षम बनाता है।
  • कुछ नमूने here

    भी दिलचस्प: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

    +0

    यच का उपयोग करके एक अवरुद्ध कतार में मानक कतार को चालू करना बहुत आसान है। लेकिन समस्या यह है - यह सिर्फ विंडोज़ के लिए है ( –

    1

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

    समाधान 1

    दर्रा (जहां लागू हो)।

    समाधान 2

    सरल का एक संग्रह बनाएं कार्यान्वयन है कि आप जबकि एक गुंजाइश ताला पकड़े कंटेनर पारित करने के लिए उपयोग कर सकते हैं बोल्ट (यह छद्म C++ पर विचार करें):

    template <typename TCollection> 
    class t_locked_collection { 
    public: 
        t_locked_collection(TCollection& inCollection, t_lock& lock) : collection(inCollection), d_lock(lock), d_nocopy() { 
        } 
    
        TCollection& collection; 
        // your convenience stuff 
    private: 
        t_scope_lock d_lock; 
        t_nocopy d_nocopy; 
    }; 
    

    तो फोन करने वाले संग्रह के साथ ताला जोड़ता है, और फिर आप अपने इंटरफ़ेस को जहां कंटेनर प्रकार का उपयोग (पास) द्वारा उपयोग करने के लिए अपडेट करते हैं। यह सिर्फ एक गरीब आदमी का वर्ग विस्तार है।

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

    एक और प्रकार होगा:

    template <typename TCollection> 
    class t_lockable_collection { 
    public: 
    // ... 
    private: 
        TCollection d_collection; 
        t_mutex d_mutex; 
    }; 
    
    // example: 
    typedef t_lockable_collection<std::vector<int> > t_lockable_int_vector; 
    

    ... जहां एक प्रकार t_locked_collection के समान अंतर्निहित संग्रह का पर्दाफाश करने के लिए इस्तेमाल किया जा सकता है। यह इंगित नहीं करना कि दृष्टिकोण मूर्खतापूर्ण है, बस मूर्ख प्रतिरोधी है।

    +0

    "मूल्य से गुजरने" के साथ, जिसका मतलब है कि कॉपी पर एक प्रतिलिपि बनाने और प्रतिलिपि बनाने के लिए मूल्य से पूरा कंटेनर पास करना है? या कंटेनर के मूल्य को मूल्य से पास करें? कृपया विस्तृत करें – steffen

    +0

    @steffen कंटेनर के तत्वों को मूल्य से पास करते हैं। कई कंटेनर इंटरफ़ेस पर विचार करते हुए, यह (** समाधान 1 **) एक इष्टतम समाधान से बहुत दूर है। दृष्टिकोण भी लगभग बेकार wrt शुद्धता है, जब तक कि आप एक लिखने को तैयार नहीं हैं अपवाद हैंडलिंग का टन और साझा पॉइंटर्स का एक टन उपयोग करें। – justin

    8

    सी ++ 11 समवर्ती कंटेनर स्वयं ही प्रदान नहीं करता है। हालांकि, लाइब्रेरी विकल्प हैं। पहले से ही उल्लिखित पीपीएल के अलावा, इंटेल टीबीबी लाइब्रेरी को न भूलें।

    इसमें समवर्ती queue, hash_map, set और vector कार्यान्वयन है। लेकिन यह न केवल थ्रेड-सुरक्षित कंटेनर लाइब्रेरी है, यह मानक एल्गोरिदम के समानांतर संस्करण के साथ आता है (फॉर-लूप, कम, सॉर्ट, ...)।

    Intel TBB website

    +1

    क्या आप मुझे समवर्ती सेट का लिंक दे सकते हैं? – user

    2

    मुझे आश्चर्य है कि कोई भी उल्लेख किया moodycamel::ConcurrentQueue हूँ। हम इसे काफी समय से इस्तेमाल कर रहे हैं और यह बहुत अच्छा प्रदर्शन करता है। यह विशिष्ट है कि इसका कार्यान्वयन लॉक-फ्री है, जो तुरंत एक विशाल गति लाता है। इसका उपयोग करने के अन्य कारण (आधिकारिक साइट से उद्धरण):

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

    कुछ मानक और तुलना उपलब्ध here, here और here हैं।

    +0

    मूडीकैमल कार्यान्वयन के साथ समस्या यह है कि यह फीफो नहीं है (यानी पॉप किए गए तत्वों का क्रम समान नहीं है धक्का तत्वों का क्रम) तो यह एक सार्वभौमिक समाधान नहीं है। –