2008-10-23 15 views
117

नए धागे का उपयोग करने और थ्रेड पूल से धागे का उपयोग करने के बीच क्या अंतर है? वहां क्या प्रदर्शन लाभ हैं और मुझे स्पष्ट रूप से बनाए गए एक के बजाय पूल से धागे का उपयोग क्यों करना चाहिए? मैं विशेष रूप से .NET के बारे में सोच रहा हूं, लेकिन सामान्य उदाहरण ठीक हैं।थ्रेड बनाम थ्रेडपूल

उत्तर

99

थ्रेड पूल

  • पुनर्प्रयोग धागे कि पहले से ही बजाय नए लोगों को (एक महंगी प्रक्रिया)
  • बनाने धागा निर्माण जब की दर थ्रॉटल के सृजन किया गया है द्वारा लगातार और अपेक्षाकृत कम संचालन के लिए लाभ प्रदान करेगा नए काम मदों के लिए अनुरोधों का एक फट

    • (मुझे इस पर विश्वास ही .NET 3.5 में किया जाता है) है आप 100 थ्रेड पूल कार्यों कतार, तो वह केवल के रूप में कई का उपयोग करेगा धागे पहले से ही इन अनुरोधों की सेवा के लिए बनाए गए हैं (उदाहरण के लिए 10 कहें)। थ्रेड पूल लगातार जांच करेगा (मुझे लगता है कि 3.5 एसपी 1 में हर 500 एमएमएस) और यदि कतारबद्ध कार्य हैं, तो यह एक नया धागा बना देगा। यदि आपके कार्य त्वरित हैं, तो नए धागे की संख्या छोटी होगी और छोटे कार्यों के लिए 10 या तो धागे का पुन: उपयोग करना 100 धागे सामने बनाने से तेज होगा।

    • यदि आपके वर्कलोड में लगातार बड़ी संख्या में थ्रेड पूल अनुरोध आ रहे हैं, तो थ्रेड पूल उपरोक्त प्रक्रिया द्वारा पूल में अधिक धागे बनाकर अपने वर्कलोड पर ट्यून करेगा ताकि वहां बड़ी संख्या में थ्रेड उपलब्ध हो प्रक्रिया हुड

एक नया बनाया जा रहा है के तहत कैसे थ्रेड पूल कार्यों पर गहराई की जानकारी में और अधिक के लिए अनुरोध करने के लिए

  • जांच Here थ्रेड खुद के और अधिक appr होगा अगर काम अपेक्षाकृत लंबे समय तक चल रहा था (शायद यह एक या दो सेकंड के आसपास होता है, लेकिन यह विशिष्ट स्थिति पर निर्भर करता है)

    @ क्रिजिज़टॉफ - थ्रेड पूल धागे पृष्ठभूमि धागे हैं जो मुख्य धागे समाप्त होने पर रुक जाएंगे। मैन्युअल रूप से बनाए गए धागे डिफ़ॉल्ट रूप से अग्रभूमि होते हैं (मुख्य धागे समाप्त होने के बाद चलते रहेंगे), लेकिन उन्हें प्रारंभ करने से पहले पृष्ठभूमि में सेट किया जा सकता है।

  • +5

    केवल एक चीज के बारे में मैं MSDN से निम्न कथन है सोच रहा हूँ (http://msdn.microsoft.com/en-us /library/1c9txz50.aspx) "पृष्ठभूमि थ्रेड निष्पादित करता है जब फोरग्राउंड थ्रेड निष्पादित करने की संख्या प्रोसेसर की संख्या से छोटी होती है।" तो क्या इसका मतलब यह है कि जब कोर के बीच काम को विभाजित करते हैं तो अग्रभूमि धागे को प्राथमिकता मिलती है? – cdiggins

    +1

    ➤ आप धागे पूल से धागे को निरस्त या बाधित नहीं कर सकते हैं। ➤ आप थ्रेड पूल से धागे में शामिल नहीं हो सकते हैं। इसे प्राप्त करने के लिए, आपको कुछ अन्य तंत्रों का उपयोग करना होगा – Zinov

    1

    धागा स्थानीय भंडारण थ्रेड पूल के साथ एक अच्छा विचार नहीं है। यह धागे को "पहचान" देता है; सभी धागे अब बराबर नहीं हैं। अब थ्रेड पूल विशेष रूप से उपयोगी होते हैं यदि आपको केवल समान धागे के समूह की आवश्यकता होती है, जो सृजन के बिना अपना काम करने के लिए तैयार हैं।

    2

    पहले के एक धागे के लिए यहाँ देखें:

    When should I not use the ThreadPool in .Net?

    सारांश यदि आप, जबकि धागे का उपयोग कर आप थोड़ा अधिक नियंत्रण देता है कई अल्पकालिक धागे अंडे की जरूरत है कि ThreadPool अच्छा है।

    1

    यदि आपको बहुत सारे धागे की आवश्यकता है, तो शायद आप थ्रेडपूल का उपयोग करना चाहते हैं। वे थ्रेड सृजन के ऊपरी हिस्से को बचाने वाले थ्रेड का पुनः उपयोग करते हैं।

    यदि आपको कुछ करने के लिए केवल एक थ्रेड की आवश्यकता है, तो थ्रेड शायद सबसे आसान है।

    7

    भी

    new Thread().Start()

    अग्रभूमि धागा कि अगर आप अपने कार्यक्रम को बंद मर नहीं spawns। थ्रेडपूल धागे पृष्ठभूमि धागे हैं जो ऐप को बंद करते समय मर जाते हैं।

    +11

    आप हमेशा थ्रेड को पृष्ठभूमि में सेट कर सकते हैं। वे डिफ़ॉल्ट रूप से सिर्फ अग्रभूमि हैं। –

    +0

    एरिक, कोई ऐसा कैसे करता है? –

    +3

    निमो: var t = new थ्रेड (...); टी। बैकग्राउंड थ्रेड = सत्य; टी। स्टार्ट(); –

    0

    सामान्य रूप से (मैंने कभी भी .NET का उपयोग नहीं किया है), संसाधन प्रबंधन उद्देश्यों के लिए एक थ्रेड पूल का उपयोग किया जाएगा। यह बाधाओं को आपके सॉफ़्टवेयर में कॉन्फ़िगर करने की अनुमति देता है। यह प्रदर्शन कारणों से भी किया जा सकता है, क्योंकि नए धागे का निर्माण महंगा हो सकता है।

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

    उदाहरण बाधा: मेरे पास केवल 10 डीबी कनेक्शन हैं, इसलिए मैं डेटाबेस तक पहुंचने के लिए केवल 10 कार्यकर्ता धागे की अनुमति दूंगा।

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

    13

    नेट कामयाब ThreadPool: -

    • आकार ही मौजूदा काम का बोझ और उपलब्ध हार्डवेयर
    • के आधार पर कार्यकर्ता धागे और पूरा होने के बंदरगाह धागे (जो विशेष रूप से सेवा के लिए उपयोग किया जाता है आईओ)
    • शामिल
    • अपेक्षाकृत अल्पकालिक परिचालनों की एक बड़ी संख्या के लिए अनुकूलित किया गया है

    अन्य थ्रेड पूल कार्यान्वयन पूर्व यह लंबे समय से चलने वाले संचालन के लिए अधिक उपयुक्त हो सकता है।

    विशेष रूप से, अपने ऐप को बनाने से रोकने के लिए थ्रेड पूल का उपयोग करें धागे। थ्रेडपूल की सबसे महत्वपूर्ण विशेषता कार्य कतार है। यही है, एक बार आपकी मशीन पर्याप्त व्यस्त होने के बाद, थ्रेडपूल तुरंत अधिक धागे को बढ़ाने के बजाय अनुरोधों को कतारबद्ध करेगा।

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

    +0

    .NET में, क्या आप थ्रेड पूल के बिना पूरा बंदरगाहों का उपयोग कर सकते हैं? मैं इस धारणा के तहत था कि async I/O विधियां एकमात्र तरीका (.NET में) थीं और वे थ्रेड पूल – Karg

    0

    पूल का उपयोग करना एक अच्छा विचार है, अगर आप नहीं जानते हैं या नियंत्रित नहीं कर सकते कि कितने धागे बनाए जाएंगे।

    सूची नियंत्रण की स्थितिबद्ध स्थिति (फ्रीज़ से बचें) पर डेटाबेस से कुछ फ़ील्ड को अपडेट करने के लिए थ्रेड का उपयोग करके फ़ॉर्म के साथ एक समस्या है। मेरे उपयोगकर्ता को डेटाबेस से एक्सेस में 5 मिनट लग गए (एक्सेस के साथ बहुत अधिक कनेक्शन) क्योंकि वह सूची की स्थिति को बहुत तेजी से बदल रहा था ...

    मुझे पता है कि मूल समस्या को हल करने का दूसरा तरीका है (सहित पहुंच का उपयोग नहीं कर रहा है) लेकिन पूलिंग एक अच्छी शुरुआत है।

    1

    सैडपूल धागे की प्राथमिक आवश्यकता कम छोटे कार्यों को संभालने के लिए है जो लगभग तुरंत पूरा होने की उम्मीद है। हार्डवेयर इंटरप्ट हैंडलर अक्सर एक स्टैकिंग संदर्भ में चलते हैं जो गैर-कर्नेल कोड के लिए उपयुक्त नहीं होगा, लेकिन एक हार्डवेयर इंटरप्ट हैंडलर यह पता लगा सकता है कि उपयोगकर्ता-मोड I/O पूर्णता कॉलबैक जितनी जल्दी हो सके चलाना चाहिए। ऐसी चीज चलाने के उद्देश्य के लिए एक नया धागा बनाना बड़े पैमाने पर ओवरकिल होगा। कुछ पूर्व-निर्मित धागे होने के बाद जिन्हें I/O पूर्णता कॉलबैक या अन्य समान चीजों को चलाने के लिए भेजा जा सकता है, वह अधिक कुशल है।

    ऐसे धागे का एक प्रमुख पहलू यह है कि यदि I/O पूर्णता विधियां हमेशा अनिवार्य रूप से पूर्ण रूप से पूर्ण होती हैं और कभी भी अवरुद्ध नहीं होती हैं, और वर्तमान में ऐसे विधियों को चलाने वाले ऐसे थ्रेड की संख्या कम से कम प्रोसेसर की संख्या के बराबर होती है, केवल जिस तरह से उपरोक्त तरीकों में से एक से पहले किसी भी अन्य थ्रेड को चलाया जा सकता है, यदि अन्य विधियों में से एक ब्लॉक या उसके निष्पादन समय में सामान्य थ्रेडिंग टाइम-स्लाइस से अधिक हो; थ्रेड पूल का उद्देश्य इरादे के रूप में उपयोग किए जाने पर उनमें से कोई भी अक्सर नहीं होना चाहिए।

    यदि किसी विधि को 100 एमएमएस के भीतर बाहर निकलने की उम्मीद नहीं की जा सकती है या जब इसे निष्पादन शुरू होता है, तो विधि को मुख्य थ्रेड पूल के अलावा किसी अन्य माध्यम से निष्पादित किया जाना चाहिए। यदि किसी के पास बहुत से कार्य हैं जो सीपीयू गहन हैं, लेकिन ब्लॉक नहीं करेंगे, तो अनुप्रयोग थ्रेड (एक प्रति सीपीयू कोर) के पूल का उपयोग करके उन्हें प्रेषित करना उपयोगी हो सकता है जो "मुख्य" थ्रेडपूल से अलग है, गैर-अवरुद्ध सीपीयू-गहन कार्यों को चलाने के दौरान कोर की तुलना में अधिक धागे प्रतिकूल होंगे। यदि, हालांकि, किसी विधि को निष्पादित करने में एक या अधिक समय लगेगा, और अपना अधिकांश समय अवरुद्ध कर देगा, विधि को समर्पित थ्रेड में चलाने की संभावना है, और लगभग निश्चित रूप से मुख्य-थ्रेडपूल थ्रेड में नहीं चलना चाहिए। यदि एक लंबे समय से चलने वाले ऑपरेशन को आई/ओ कॉलबैक जैसी किसी चीज से ट्रिगर किया जाना चाहिए, तो किसी को कॉलबैक के पहले लंबे समय से चलने वाले ऑपरेशन के लिए धागा शुरू करना चाहिए और इसे मॉनीटर पर इंतजार करना चाहिए जो कॉलबैक दालें, या अन्यथा कॉलबैक बाहर निकलने के दौरान कॉलबैक लॉन्च करने के लिए एक नया थ्रेड लॉन्च करता है, प्रभावी ढंग से थ्रेडपूल पर अपना धागा लौटता है।

    2

    मैं इनके लिए सापेक्ष संसाधन उपयोग के बारे में curios था और विंडोज़ 8 पर .NET 4.0 रिलीज बिल्ड का उपयोग कर अपने 2012 ड्यूल-कोर इंटेल आई 5 लैपटॉप पर एक बेंचमार्क चलाया। थ्रेड पूल ने 0.035ms औसत ले लिया जहां थ्रेड ले गए थे 5.06ms का औसत दूसरे शब्दों में पूल में थ्रेड बड़ी संख्या में अल्पकालिक धागे के लिए 300x तेज शुरू हुआ। कम से कम परीक्षण सीमा (100-2000) धागे में, प्रति थ्रेड का कुल समय काफी स्थिर लग रहा था।

    इस कोड है कि बेंचमार्क किया गया था:

    for (int i = 0; i < ThreadCount; i++) { 
         Task.Run(() => { }); 
        } 
    
        for (int i = 0; i < ThreadCount; i++) { 
         var t = new Thread(() => { }); 
         t.Start(); 
        } 
    

    enter image description here

    +3

    का उपयोग करते हैं, मुझे लगता है कि ऐसा इसलिए है क्योंकि ThreadPool नए बनाने के बजाय बनाए गए धागे का पुन: उपयोग करता है (बहुत महंगा क्या है) – fabriciorissetto

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