क्या ऐसे कोई मामले हैं जब नए निर्माणों में से एक के बजाय एक सादे पुराने थ्रेड ऑब्जेक्ट का उपयोग करना बेहतर होता है?


112

मैं ब्लॉग पोस्ट में बहुत सारे लोगों को देखता हूं और यहाँ पर SO के Threadहाल के संस्करणों में वर्ग के उपयोग के खिलाफ या तो परहेज या सलाह देता हूं (और मेरा मतलब है 4.0+ और इसके अलावा, Taskदोस्तों के साथ)। पहले भी, इस तथ्य के बारे में बहसें हुई थीं कि एक सादे पुराने धागे की कार्यक्षमता को कई मामलों में ThreadPoolकक्षा द्वारा प्रतिस्थापित किया जा सकता है ।

इसके अलावा, अन्य विशिष्ट तंत्र Threadवर्ग को कम आकर्षक बनाने के लिए आगे बढ़ा रहे हैं , जैसे Timerकि बदसूरत Thread+ Sleepकॉम्बो की जगह , जबकि हमारे पास जीयूआई के लिए BackgroundWorker, आदि।

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

तो मेरा सवाल यह है कि Threadक्या उपरोक्त मामलों में से किसी एक के बजाय एक पुरानी पुरानी वस्तु का उपयोग करना आवश्यक या उपयोगी है ?


4
नाइटपिक के लिए नहीं (या शायद ... :)), लेकिन यह .NET है (यानी सी # तक सीमित नहीं है)।

11
अब तक इस प्रश्न का उत्तर देने वाले उपयोगकर्ता के लिए औसत प्रतिनिधि है 64.5k। काफी प्रभावशाली दिखा
zzzzBov

1
@zzzzBov: मैं अपना जवाब पोस्ट करने के बारे में सोच रहा था, लेकिन अब मैं औसत नीचे लाने के डर से नहीं कर सकता :)
ब्रायन गिदोन

@BrianGideon, मुझे कोई कारण नहीं दिखता है कि आपको इस सवाल का जवाब देने से क्यों रोकना चाहिए।
zzzzBov

@ ब्रायन गिदोन: हर तरह से, कृपया पोस्ट करें। :)
ट्यूडर

जवाबों:


107

थ्रेड क्लास को अप्रचलित नहीं किया जा सकता क्योंकि स्पष्ट रूप से यह उन सभी अन्य पैटर्नों का कार्यान्वयन विवरण है , जिनका आप उल्लेख करते हैं।

लेकिन यह वास्तव में आपका सवाल नहीं है; आपका सवाल है

क्या ऐसे कोई मामले हैं जब उपरोक्त निर्माणों में से एक के बजाय एक सादे पुराने थ्रेड ऑब्जेक्ट का उपयोग करना आवश्यक या उपयोगी हो?

ज़रूर। ठीक उन मामलों में जहां उच्च-स्तरीय निर्माणों में से एक आपकी आवश्यकताओं को पूरा नहीं करता है।

मेरी सलाह यह है कि यदि आप खुद को ऐसी स्थिति में पाते हैं, जहां मौजूदा उच्च-अमूर्त उपकरण आपकी आवश्यकताओं को पूरा नहीं करते हैं, और आप थ्रेड्स का उपयोग करके एक समाधान लागू करना चाहते हैं, तो आपको उस लापता अमूर्त की पहचान करनी चाहिए जिसकी आपको वास्तव में आवश्यकता है , और फिर उस अमूर्त को लागू करें। धागे का उपयोग करना , और फिर अमूर्त का उपयोग करें


33
सभी अच्छी सलाह। लेकिन क्या आपके पास एक उदाहरण है जहां एक सादे पुराने धागे की वस्तु नए निर्माणों में से एक के लिए बेहतर हो सकती है?
रॉबर्ट हार्वे

कुछ कोड लोड करने के लिए समय के मुद्दों के साथ कई थ्रेड को डीबग करना कई बार बहुत आसान हो सकता है फिर अन्य 'उच्च' स्तर के निर्माण का उपयोग करना। और आपको वैसे भी थ्रेड्स को काम करने और उपयोग करने की बुनियादी जानकारी की आवश्यकता है।
कोडिंगबारफील्ड

उत्तर के लिए धन्यवाद, एरिक। नई थ्रेडिंग सुविधाओं के बारे में हालिया बमबारी के तहत, यह भूलना आसान है कि कभी-कभी पुराने धागे की जरूरत होती है। खैर, मुझे लगता है कि नंगे-धातु का ज्ञान वैसे भी उपयोगी है।
ट्यूडर

15
@ रोबर्टहेयर: ज़रूर। उदाहरण के लिए, यदि आपके पास एक क्लासिक "निर्माता / उपभोक्ता" स्थिति है, जहां आप चाहते हैं कि एक धागा एक काम कतार से बाहर सामान लेने के लिए समर्पित हो और दूसरा धागा काम की कतार में सामान डालने के लिए समर्पित हो। दोनों पाश सदा के लिए; वे उन कार्यों के लिए अच्छी तरह से मैप नहीं करते हैं जो आप थोड़ी देर के लिए करते हैं और फिर एक परिणाम प्राप्त करते हैं। आपको थ्रेड पूल की आवश्यकता नहीं है क्योंकि केवल दो धागे हैं। और आप अपने ताले और संकेतों के उपयोग से चालाक हो सकते हैं ताकि यह सुनिश्चित हो सके कि कतार लंबे समय तक दूसरे धागे को अवरुद्ध किए बिना सुरक्षित रखी जाए।
एरिक लिपर्ट

@ एरिक: टीपीएल डेटाफ़्लो द्वारा पहले से ही पेश किए गए ऐसे अमूर्त नहीं हैं ?
१ek:५४ पर एलोन गुरिलनेक

52

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

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

एक समान नस में, कई मामलों के लिए बेहतर फिट होने के .NETबावजूद, सरणियों के उपयोग को मना नहीं करता है, List<T>जहां लोग सरणियों का उपयोग करते हैं। केवल इसलिए कि आप अभी भी उन चीजों का निर्माण करना चाहते हैं जो मानक देयता से आच्छादित नहीं हैं।


6
सिर्फ इसलिए कि एक ऑटोमैटिक ट्रांसमिशन 99% समय काम करता है, इसका मतलब यह नहीं है कि मैन्युअल ट्रांसमिशन में कोई मूल्य नहीं है, यहां तक ​​कि ड्राइवर वरीयता को भी अनदेखा नहीं करता है।
ग्वेंटे

4
ड्राइविंग मुहावरों से बहुत परिचित नहीं है कि मैं एक साइकिल चालक और सार्वजनिक परिवहन उपयोगकर्ता हूं। लेकिन एक मैनुअल ट्रांसमिशन एक स्वत: एक के दिल में नहीं है - यह एक यांत्रिक हाथ नहीं है जो एक छड़ी चलती है। यह वास्तव में दूसरे पर एक अमूर्त नहीं है, जहां तक ​​मैं इसे देख सकता हूं।
जोए

2
आप दूसरे पैराग्राफ में "थ्रेड" शब्द को "अनवांटेड कोड" से बदल सकते हैं और यह अभी भी सही होगा
कॉनरेड फ्रीक्स

1
@ जोए: ओह, मैंने सोचा था कि आप अप्रचलन की कीमत पर, अप्रचलन की कीमत पर, अप्रचलन टुकड़े का मतलब है, भले ही इसकी आवश्यकता कभी नहीं होगी। BTW तकनीकी रूप से एक मैनुअल ट्रांसमिशन का दिलचस्प हिस्सा वैसे भी क्लच है।
गुवाँटे

3
तुम लोग वास्तव में संचरण रूपक के साथ जाना चाहते हैं, सबसे अनुक्रमिक प्रसारण (जैसे बीएमडब्ल्यू SMG संचरण के रूप में) कर रहे हैं , वास्तव में, एक कंप्यूटर के साथ मैनुअल प्रसारण क्लच और गियर चयनकर्ता ऑपरेशन किया। वे पारंपरिक ऑटोमेटिक्स की तरह ग्रहीय गियर सिस्टम नहीं हैं।
एडम रॉबिन्सन

13

Taskऔर Threadअलग-अलग सार हैं। यदि आप एक धागा मॉडल करना चाहते हैं, तो Threadकक्षा अभी भी सबसे उपयुक्त विकल्प है। उदाहरण के लिए, यदि आपको वर्तमान थ्रेड के साथ सहभागिता करने की आवश्यकता है, तो मुझे इसके लिए कोई बेहतर प्रकार दिखाई नहीं देता है।

हालाँकि, जैसा कि आप बताते हैं .NET ने कई समर्पित सार जोड़े हैं जो Threadकई मामलों में बेहतर हैं ।


9

Threadवर्ग यह अभी भी विशेष परिस्थितियों में उपयोगी है अप्रचलित नहीं है,।

जहां मैं काम करता हूं, हमने सामग्री प्रबंधन प्रणाली के हिस्से के रूप में एक 'बैकग्राउंड प्रोसेसर' लिखा है: एक विंडोज सेवा जो निर्देशिकाओं, ई-मेल पतों और आरएसएस फ़ीड की निगरानी करती है, और हर बार कुछ नया शो उस पर एक कार्य निष्पादित करता है - आम तौर पर आयात करने के लिए डेटा।

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


मुझे नहीं पता है कि सीधे थ्रेड का उपयोग करना यहां सही समाधान है, लेकिन वास्तव में थ्रेड को जाने के लिए उदाहरण देने के लिए +1 आवश्यक था।
Oddthinking

6

नए विकल्प सीधे (महंगे) धागों का सीधा उपयोग और प्रबंधन करते हैं।

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

जो समानांतर में सामान करने का एक बहुत महंगा और अपेक्षाकृत जटिल तरीका है।

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


5

" किसी भी मामले में जब यह आवश्यक हो या एक पुराने पुराने थ्रेड ऑब्जेक्ट का उपयोग करने के लिए उपयोगी हो " के प्रश्न का उत्तर देने के लिए , मैं कहूंगा कि एक पुराना पुराना थ्रेड उपयोगी है (लेकिन आवश्यक नहीं) जब आपके पास एक लंबी चलने वाली प्रक्रिया है जिसे आपने जीता है ' टी कभी एक अलग धागे से बातचीत।

उदाहरण के लिए, यदि आप एक ऐसा एप्लिकेशन लिख रहे हैं जो किसी प्रकार की संदेश कतार से संदेश प्राप्त करने के लिए सब्सक्राइब करता है और आप एप्लिकेशन उन संदेशों को संसाधित करने से अधिक करने जा रहे हैं तो थ्रेड का उपयोग करना उपयोगी होगा क्योंकि थ्रेड होगा आत्म-निहित (यानी आप इसे पूरा करने के लिए इंतजार नहीं कर रहे हैं), और यह अल्पकालिक नहीं है। थ्रेडपूल वर्ग का उपयोग अल्पकालिक कार्य वस्तुओं के एक समूह को कतारबद्ध करने के लिए अधिक है और थ्रेडपूल वर्ग को एक नए थ्रेड के रूप में प्रत्येक को कुशलतापूर्वक संसाधित करने की अनुमति देता है। कार्य का उपयोग किया जा सकता है जहां आप सीधे थ्रेड का उपयोग करेंगे, लेकिन ऊपर के परिदृश्य में मुझे नहीं लगता कि वे आपको ज्यादा खरीदेंगे। वे धागे से अधिक आसानी से बातचीत करने में आपकी सहायता करते हैं (जो उपरोक्त परिदृश्य नहीं है)


मैं इस बात से सहमत हूं कि ज्यादातर नई नई समानताएं छोटी-छोटी बारीक कामों के लिए तैयार की जाती हैं, और लंबे समय तक चलने वाले धागों को अभी भी लागू किया जाना चाहिए System.IO.Threading.Thread
बेन वोइगट

4

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


अरे, यह वास्तव में एक बहुत अच्छा उदाहरण है! धन्यवाद। मैंने ऐसी रूपरेखाओं के बारे में नहीं सोचा है जो नई सुविधाओं का समर्थन नहीं करती हैं।
ट्यूडर

3

आप ADO.NET को थ्रेड क्लास की तुलना कर सकते हैं। यह काम पाने के लिए अनुशंसित उपकरण नहीं है, लेकिन इसके अप्रचलित नहीं हैं। अन्य उपकरण काम को आसान बनाने के लिए इसके शीर्ष पर बनाते हैं।

अन्य चीजों पर थ्रेड क्लास का उपयोग करना गलत नहीं है, खासकर अगर उन चीजों को एक कार्यक्षमता प्रदान नहीं की जाती है जो आपको चाहिए।


3

यह निश्चित रूप से अप्रचलित नहीं है।

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

तो मेरा प्रश्न यह है कि क्या उपरोक्त मामलों में से एक के बजाय एक सादे पुराने थ्रेड ऑब्जेक्ट का उपयोग करना आवश्यक या उपयोगी है?

मैं थ्रेड्स और लॉक के साथ जाऊंगा तभी गंभीर प्रदर्शन समस्याएं, उच्च प्रदर्शन लक्ष्य होंगे।


3

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

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

उस स्थिति में, मुझे थ्रेड क्लास के साथ सीधे काम करने का एक बेहतर तरीका नहीं मिला है। जैसा कि एरिक लिपर्ट ने उल्लेख किया है, अन्य बस उच्च-स्तरीय अमूर्त हैं, और यह निम्न-स्तरीय कक्षाओं के साथ काम करने के लिए उपयुक्त है जब उपलब्ध उच्च-स्तरीय कार्यान्वयन आपकी आवश्यकता को पूरा नहीं करते हैं। जैसे आपको कभी-कभी Win32 API कॉल करने की आवश्यकता होती है। जब .NET आपकी सटीक जरूरतों को पूरा नहीं करता है, तो हमेशा ऐसे मामले होंगे जहां हाल की "प्रगति" के बावजूद थ्रेड क्लास सबसे अच्छा विकल्प है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.