2010-08-05 23 views
58

ऐसा लगता है कि मुझे अंततः मेरे डेल्फी 200 कार्यक्रम में कुछ प्रकार के धागे को लागू करने के लिए मिला है। अगर ऐसा करने का केवल एक ही तरीका था, तो मैं बंद होकर दौड़ूंगा। लेकिन मुझे कई संभावनाएं दिखाई देती हैं।डेल्फी में थ्रेडिंग करने के विभिन्न तरीकों के बीच मैं कैसे चुनाव करूं?

क्या कोई यह समझा सकता है कि इनके बीच क्या अंतर है और मैं एक दूसरे को क्यों चुनूं।

  1. डेल्फी

  2. AsyncCalls में TThread वर्ग Primoz Gabrijelcic (gabr)

  3. द्वारा Andreas Hausladen

  4. OmniThreadLibrary द्वारा ... किसी भी दूसरों?


संपादित करें:

मैं सिर्फ मार्च 2010 में Gabr द्वारा एक उत्कृष्ट लेख को पढ़ने के (कोई 10) Blaise Pascal Magazine शीर्षक के मुद्दे "चार तरीके एक धागा बनाने के लिए"। आपको पत्रिका में सामग्री प्राप्त करने के लिए सब्सक्राइब करना होगा, इसलिए कॉपीराइट द्वारा, मैं यहां इसके बारे में कुछ भी पुन: पेश नहीं कर सकता।

संक्षेप में, गैबर टीटीएचड्स, सीधी विंडोज एपीआई कॉल, एंडी एसिंककॉल और अपनी ओमनी थ्रेड लाइब्रेरी का उपयोग करने के बीच के अंतर का वर्णन करता है। वह अंत है कि कम से निष्कर्ष निकालना है:

"मैं यह नहीं कह रहा हूँ आप शास्त्रीय डेल्फी रास्ता (TThread) की तुलना में कुछ और चुनने के लिए है कि लेकिन यह अभी भी आप की है विकल्पों में से सूचित करने के लिए अच्छा है"

मागी का जवाब बहुत गहन है और सुझाव देता है कि OmniThreadLibrary बेहतर हो सकता है। लेकिन मुझे अभी भी हर किसी के विचारों में दिलचस्पी है कि मैं (या किसी को भी) अपने आवेदन के लिए अपनी थ्रेडिंग विधि चुननी चाहिए।

और आप सूची में जोड़ सकते हैं:

। 4. विंडोज एपीआई

पर प्रत्यक्ष कॉल। 5. Misha Charrett'sCSI Distributed Application Framework जैसा कि उनके जवाब में लचलन जी द्वारा सुझाया गया है।


निष्कर्ष:

मैं शायद OmniThreadLibrary के साथ जाने के लिए जा रहा हूँ। मुझे गैबर का काम पसंद है। मैंने कई साल पहले अपने प्रोफाइलर जीपीप्रोफाइल का इस्तेमाल किया था, और मैं वर्तमान में अपने जीपीएसटींगशैश का उपयोग कर रहा हूं जो वास्तव में ओटीएल का हिस्सा है।

मेरी एकमात्र चिंता 64-बिट या यूनिक्स/मैक प्रोसेसिंग के साथ काम करने के लिए इसे अपग्रेड कर सकती है जब एम्बरकैडेरो उस कार्यक्षमता को डेल्फी में जोड़ता है।

उत्तर

41

यदि आपको बहु-थ्रेडिंग के साथ अनुभव नहीं हुआ है तो आपको शायद TThread से शुरू नहीं करना चाहिए, क्योंकि यह मूल थ्रेडिंग पर एक पतली परत है। मैं इसे किनारों के चारों ओर थोड़ा मोटा होना मानता हूं; यह डेल्फी 2 के साथ परिचय के बाद से बहुत कुछ विकसित नहीं हुआ है, ज्यादातर किलिक्स समय सीमा में लिनक्स संगतता की अनुमति देने के लिए और अधिक स्पष्ट दोषों को ठीक करने के लिए परिवर्तन (जैसे टूटी हुई एमआरडब्ल्यू कक्षा को ठीक करना, और अंततः Suspend() और Resume() को नवीनतम में हटा देना डेल्फी संस्करण)।

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

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

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

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

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

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

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

+3

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

6

टीटीएचड एक साधारण वर्ग है जो विंडोज थ्रेड को समाहित करता है। आप एक निष्पादक विधि के साथ एक वंशज वर्ग बनाते हैं जिसमें कोड को निष्पादित करना चाहिए, थ्रेड बनाएं और इसे चलाने के लिए सेट करें और कोड निष्पादित हो।

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

मैंने पुस्तकालय का इतना उपयोग नहीं किया है, इसलिए मैं वास्तव में आपको दोनों के बीच तुलना नहीं दे सकता। उन्हें आज़माएं और देखें कि वे क्या कर सकते हैं, और कौन सा आपको बेहतर महसूस करता है।

6

एक और कम ज्ञात डेल्फी थ्रेडिंग लाइब्रेरी, मिशा चरेटेट CSI Application Framework है।

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

शुरू करने के लिए सीखने की एक छोटी सी चीज है लेकिन एक बार जब आप जा रहे हैं तो आपको पारंपरिक पारंपरिक थ्रेडिंग मुद्दों जैसे कि डेडलॉक्स और सिंक्रनाइज़ेशन के बारे में चिंता करने की ज़रूरत नहीं है, ढांचा आपके लिए अधिकतर का ख्याल रखता है।

मिशा साल के लिए इसे विकसित कर रहा है और अभी भी सक्रिय रूप से ढांचे और दस्तावेज़ीकरण में सक्रिय रूप से सुधार कर रहा है। वह प्रश्नों का समर्थन करने के लिए हमेशा उत्तरदायी रहता है।

6

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

मैंने असिनकॉल्स को देखा है लेकिन यह जो भी मैं चाहता था वह पर्याप्त नहीं करता था। एक बात यह है कि "सिंक्रनाइज़" फ़ंक्शन (ओटीएल से गायब) है, इसलिए यदि आप उस पर निर्भर हैं तो आप इसके लिए पूरी तरह से ऐन्सस्कॉल के साथ जा सकते हैं। संदेश पास करने का उपयोग कर आईएमओ सिंक्रनाइज़ करने की नीचता को न्यायसंगत साबित करने के लिए पर्याप्त नहीं है, इसलिए नीचे बकवास करें और संदेशों का उपयोग कैसे करें सीखें।

तीन मैं काफी हद तक उदाहरण के संग्रह की वजह से OTL पसंद करते हैं, लेकिन यह भी इसे और अधिक आत्म निहित है, क्योंकि के

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

OTL साथ

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

1

मैं जानता हूँ कि यह सबसे उन्नत विधि :-) नहीं है और हो सकता है यह सीमाओं भी है, लेकिन मैं सिर्फ कोशिश की प्रणाली। BeginThread और इसे काफी सरल पाया - शायद प्रलेखन की गुणवत्ता के कारण मैं इसका जिक्र कर रहा था ...http://www.delphibasics.co.uk/RTL.asp?Name=BeginThread

सबसे बड़ा कारक मैं नई बातें जानने की कोशिश कर में मिल रहा है यही कारण है, दस्तावेज की गुणवत्ता (IMO नील मोफ़ात MSDN एक बात या दो सिखाने सकता है), नहीं यह मात्रा है। कुछ घंटों में यह सब कुछ लिया गया था, फिर मैं अपने काम को करने के लिए थ्रेड कैसे प्राप्त करने के बारे में चिंता करने के बजाय असली काम पर वापस आ गया था।

संपादित वास्तव में रोब कैनेडी रास्ता रोब कैनेडी एक ही पोस्ट में TThread बताते BeginThread यहाँ समझा BeginThread Structure - Delphi

संपादित वास्तव में एक बहुत अच्छा काम करता है, मुझे लगता है कि मैं TThread कल का उपयोग करने के लिए अपने कोड बदल देंगे। कौन जानता है कि यह अगले हफ्ते कैसा दिखता है! (AsyncCalls शायद)

+0

मैं पूरी तरह से असहमत हूं। मुख्य थ्रेड के बाहर वीसीएल जीयूआई कार्यों को कॉल करने की तुलना में शुरुआत करने के लिए एक बुरी चीज की कल्पना करना मुश्किल है। कोड या तो 'IsMultiTread' सेट नहीं करता है। यदि कोई इसके बाद अपना स्वयं का कोड मॉडल करता है, तो चरण कुछ हार्ड-टू-ट्रैक-डाउन बग के लिए सेट किया गया है। – mghie

+0

@ मिगी, ओह, आप डेल्फी मूलभूत पृष्ठ पर उदाहरण का जिक्र कर रहे हैं। खैर मैंने इसे एक अलग धागे को कैसे लात मारने का एक उदाहरण के रूप में देखा। मैंने थ्रेड से जीयूआई संचालन की जरूरी वकालत के रूप में इसके बारे में नहीं सोचा था। मुझे खुशी है कि मैं उस पर ठोकर खाई। TThread, AsyncCalls, या OTL मुझे जो कुछ भी चाहता था उसे हासिल करने के लिए मुझे कुछ घंटों (कम से कम) ले गया होता (जो 1 है: मल्टीथ्रेडिंग में एक सरल परिचय, और 2: कोड का एक कामकाजी टुकड़ा ताकि मैं बाकी के साथ जारी रख सकूं धागे के साथ पूरे दिन बिताए रखने के बजाय मेरा काम!)। अब मैं दूसरों को अपनी गति से सीख सकता हूं, कोई तात्कालिकता नहीं :-) – Sam

+0

@ मिगी, बीटीडब्ल्यू, मैंने पहले पढ़ा था कि जीयूआई ऑपरेशंस मुख्य धागे तक ही सीमित होना चाहिए, इसलिए वास्तव में मैंने यही किया। मैंने थ्रेड का इस्तेमाल वेब सेवा को कॉल करने के लिए किया और डेटा को मुख्य थ्रेड पर वापस फ़ीड किया, जिसने यूआई को अपडेट किया। यह अभी के लिए महान काम करता है। – Sam

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