2012-02-20 16 views
12

मैं std::async के बारे में और कैसे एक भविष्य संकलक कार्यान्वयन में इसका इस्तेमाल करना चाहिए सोच रहा हूँ। हालांकि, अभी मैं कुछ ऐसी चीज से फंस गया हूं जो डिज़ाइन दोष की तरह महसूस करता है।std :: async - कार्यान्वयन निर्भर उपयोग?

std::asynclaunch::async के संभवतः दो प्रकारों के साथ बहुत अधिक कार्यान्वयन निर्भर है, जो एक कार्य को एक नए थ्रेड में लॉन्च करता है और एक थ्रेड-पूल/टास्क-शेड्यूलर का उपयोग करता है।

हालांकि, एक है जो इन वेरिएंट कि std::async लागू करने के लिए उपयोग किया जाता है में से एक के आधार उपयोग काफी भिन्नता होगी।

"थ्रेड-पूल" आधारित संस्करण के लिए आप ओवरहेड्स के बारे में ज्यादा चिंता किए बिना बहुत से छोटे कार्यों को लॉन्च करने में सक्षम होंगे, हालांकि, अगर किसी एक कार्य में कुछ कार्य अवरुद्ध हो जाए तो क्या होगा?

दूसरी ओर "लॉन्च न्यू थ्रेड" संस्करण को अवरुद्ध कार्यों के साथ समस्याएं नहीं आतीं, दूसरी तरफ, लॉन्च करने और कार्यों को निष्पादित करने का ओवरहेड बहुत अधिक होगा।

धागा पूल: + कम भूमि के ऊपर, -never कभी

लांच नया थ्रेड ब्लॉक: + ब्लॉक के साथ ठीक, ऊंची भूमि के ऊपर

तो मूल रूप से क्रियान्वयन के आधार पर जिस तरह से हम का उपयोग std::async बहुत ज्यादा सावधान होगा। यदि हमारे पास एक प्रोग्राम है जो एक कंपाइलर के साथ अच्छी तरह से काम करता है, तो यह किसी अन्य पर काम कर सकता है।

इस डिजाइन से है? या क्या मैं कुछ न कुछ भूल रहा हूं? क्या आप इसे एक बड़ी समस्या के रूप में मानेंगे?

वर्तमान विनिर्देश में std::oversubscribe(bool) जैसे कुछ std::async पर निर्भरता के कार्यान्वयन को सक्षम करने के लिए मुझे कुछ याद आ रहा है।

संपादित करें: जहां तक ​​मैंने पढ़ा है, सी ++ 11 मानक दस्तावेज़ इस संबंध में कोई संकेत नहीं देता है कि std::async पर भेजे गए कार्यों को ब्लॉक किया जा सकता है या नहीं।

+0

बस एक अतिरिक्त के रूप में: http://en.cppreference.com/w/cpp/thread/async 'std :: async' कॉल को अवरुद्ध करने का एक सरल और यथार्थवादी उदाहरण प्रदान करता है। – KillianDS

+0

आपको लगता है कि थ्रेड पूल का एक निश्चित आकार है। व्यावहारिक रूप से, कई गतिशील रूप से आकार में होते हैं, इसलिए अवरोधन कोई मुद्दा नहीं है। –

+0

@MooingDuck: न तो टीबीबी और न ही कॉन्सर्ट में "गतिशील रूप से" थ्रेड पूल आकार हैं। आप किस थ्रेड पूल के बारे में जानते हैं जो गतिशील रूप से आकार में हैं? और यहां तक ​​कि यदि आपके पास गतिशील रूप से आकार का थ्रेड पूल है, तो इसके बजाय आपको ओवरसब्सक्रिप्शन की समस्या मिलती है और नए थ्रेड जोड़ने और पुराने लोगों को हटाने का ट्रैक रखने के लिए जो कुछ भी ह्यूरिस्टिक्स की आवश्यकता होती है, उसके ऊपर की ओर बढ़ जाती है। – ronag

उत्तर

11

std::async कार्यों std::launch::async रन की नीति के साथ शुरू किया, "के रूप में एक नया सूत्र में यदि" तो धागा पूल वास्तव में समर्थित नहीं हैं --- क्रम फाड़ और प्रत्येक के बीच में सभी धागे की स्थानीय चर पुन: करने के लिए होगा कार्य निष्पादन, जो सीधा नहीं है।

इसका यह भी अर्थ है कि आप std::launch::async की नीति के साथ कार्यवाही शुरू करने की अपेक्षा कर सकते हैं।स्टार्ट-अप विलंब हो सकता है, और यदि आपके पास प्रोसेसर की तुलना में अधिक चलने वाले धागे हैं, तो कार्य-स्विचिंग होगी, लेकिन उन्हें चलाना चाहिए, और डेडलॉक नहीं करना चाहिए क्योंकि कोई दूसरे की प्रतीक्षा करता है।

एक कार्यान्वयन एक एक्सटेंशन प्रदान करने का विकल्प चुन सकता है जो आपके कार्यों को थ्रेड पूल में चलाने की अनुमति देता है, इस स्थिति में यह अर्थशास्त्र दस्तावेज करने के लिए उस कार्यान्वयन पर निर्भर करता है।

+1

+1, "जैसा कि एक नए धागे में" और थ्रेड-स्थानीय चर के लिए। – ronag

+0

एमएसवीसी का एसिंक एक थ्रेडपूल का उपयोग करता है। मैं कल्पना करता हूं कि जब कोई धागा "कार्य" पूरा करता है, तो यह पूर्ण होने की रिपोर्ट करता है, फिर उसके थ्रेड स्थानीय को रीसेट करता है, फिर एक नया कार्य प्रतीक्षा करता है। इसका मतलब यह होगा कि उपयोगकर्ता कोड को थ्रेड स्थानीय रीसेट के लिए कभी भी इंतजार नहीं करना पड़ेगा। –

+0

मुझे एमएसवीसी कार्यान्वयन के विवरण नहीं पता हैं, हालांकि मानक के लिए 'भविष्य' तैयार होने से पहले 'thread_local' चर नष्ट हो गए हैं। –

1

मैं नए थ्रेड लॉन्च करने के लिए कार्यान्वयन की अपेक्षा करता हूं, और थ्रेड पूल को सी ++ के भविष्य के संस्करण में छोड़ देता हूं जो इसे मानकीकृत करता है। क्या कोई कार्यान्वयन है जो थ्रेड पूल का उपयोग करता है?


MSVC initally उनके कन्करेंसी क्रम के आधार पर एक थ्रेड पूल का इस्तेमाल किया। STL Fixes In VS 2015, Part 2 के अनुसार यह हटा दिया गया है। सी ++ विनिर्देश ने चालाक चीजों को करने के लिए कार्यान्वयन करने वालों के लिए कुछ जगह छोड़ी, हालांकि मुझे नहीं लगता कि यह थ्रेड पूलिंग कार्यान्वयन के लिए पर्याप्त जगह छोड़ दिया गया है। विशेष रूप से मुझे लगता है कि spec को अभी भी आवश्यक है कि thread_local ऑब्जेक्ट्स को नष्ट कर दिया जाएगा और पुनर्निर्मित किया जाएगा, लेकिन ConcRT के साथ उस थ्रेड पूलिंग ने इसका समर्थन नहीं किया होगा।

+1

यदि मुझे सही मूल माइक्रोसॉफ्ट ने गोइंग नेटिव 2012 सम्मेलन के दौरान याद किया है कि 'std :: async' Concrt का उपयोग करेगा। मुझे नहीं पता कि जीसीसी और क्लैंग की क्या योजना है। – ronag

+0

एमएसवीसी इस बिंदु पर एक थ्रेडपूल का उपयोग करता है, न तो libC++ और न ही libstdC++ पूल का उपयोग करते हुए मैंने चेक किया। –

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