क्या आप एसटीए और एमटीए की व्याख्या कर सकते हैं?


391

क्या आप एसटीए और एमटीए को अपने शब्दों में समझा सकते हैं?

इसके अलावा, अपार्टमेंट थ्रेड्स क्या हैं और क्या वे केवल COM से संबंधित हैं? यदि हां, तो क्यों?


1
यह भी देखें: COM अपार्टमेंट्स भाग 1 , भाग 2
जूनियर

जवाबों:


361

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

STA मॉडल का उपयोग COM ऑब्जेक्ट के लिए किया जाता है जो थ्रेड सुरक्षित नहीं हैं। इसका मतलब है कि वे अपने स्वयं के सिंक्रनाइज़ेशन को नहीं संभालते हैं। इसका एक सामान्य उपयोग यूआई घटक है। इसलिए यदि किसी अन्य थ्रेड को ऑब्जेक्ट के साथ इंटरैक्ट करने की आवश्यकता होती है (जैसे कि एक फॉर्म में एक बटन को पुश करना) तो संदेश एसटीआर थ्रेड पर मार्शल्ड हो जाता है। विंडोज़ संदेश संदेश पंपिंग प्रणाली इसका एक उदाहरण है।

यदि COM ऑब्जेक्ट अपने स्वयं के सिंक्रनाइज़ेशन को संभाल सकता है तो एमटीए मॉडल का उपयोग किया जा सकता है जहां कई थ्रेड्स को बिना मार्शड कॉल के ऑब्जेक्ट के साथ बातचीत करने की अनुमति मिलती है।


1
अधिक जानकारी के लिए एक अच्छा पढ़ा: जानकारी: वर्णन और OLE थ्रेडिंग मॉडल के कार्य
noseratio 14

208

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

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

एक अपार्टमेंट वस्तुओं के रहने की जगह है, और उनमें एक या एक से अधिक धागे होते हैं। अपार्टमेंट परिभाषित करता है कि कॉल होने पर क्या होता है। एक अपार्टमेंट में वस्तुओं को कॉल प्राप्त किया जाएगा और उस अपार्टमेंट में किसी भी थ्रेड पर संसाधित किया जाएगा, इस अपवाद के साथ कि सही अपार्टमेंट में पहले से ही थ्रेड द्वारा कॉल स्वयं (यानी ऑब्जेक्ट पर एक सीधा कॉल) द्वारा संसाधित किया जाता है।

धागे या तो सिंगल-थ्रेडेड अपार्टमेंट में हो सकते हैं (जिस स्थिति में वे उस अपार्टमेंट में एकमात्र धागा हैं) या मल्टी-थ्रेड अपार्टमेंट में। वे निर्दिष्ट करते हैं कि जब धागा उस धागे के लिए COM को इनिशियलाइज़ करता है।

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

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

सादगी के लिए हम केवल डीएलएल में लागू वस्तुओं पर विचार करेंगे, जो रजिस्ट्री में विज्ञापन करती हैं कि वे क्या समर्थन करते हैं, जो ThreadingModelउनकी कक्षा की कुंजी के लिए मूल्य निर्धारित करके । चार विकल्प हैं:

  • मुख्य धागा ( ThreadingModelमूल्य मौजूद नहीं)। ऑब्जेक्ट को होस्ट के मुख्य UI थ्रेड पर बनाया गया है, और सभी कॉल उस थ्रेड पर marshalled हैं। वर्ग कारखाना केवल उस धागे पर बुलाया जाएगा।
  • Apartment। यह इंगित करता है कि वर्ग किसी भी एकल-थ्रेडेड-मोड थ्रेड पर चल सकता है। यदि वह थ्रेड जो इसे STA थ्रेड बनाता है, ऑब्जेक्ट उस थ्रेड पर चलेगा, अन्यथा यह मुख्य STA में बनाया जाएगा - यदि कोई मुख्य STA मौजूद नहीं है, तो इसके लिए एक STA थ्रेड बनाया जाएगा। (इसका मतलब है कि एमटीए थ्रेड्स जो अपार्टमेंट ऑब्जेक्ट्स बनाते हैं, सभी कॉल को एक अलग थ्रेड में मार्शेल करेंगे।) क्लास फैक्ट्री को कई एसटीए थ्रेड्स द्वारा समवर्ती कहा जा सकता है, इसलिए इसे इसके खिलाफ अपने आंतरिक डेटा की रक्षा करना होगा।
  • Free। यह एमटीए में चलाने के लिए डिज़ाइन की गई कक्षा को इंगित करता है। यह हमेशा एमटीए में लोड होगा, भले ही एसटीए थ्रेड द्वारा बनाया गया हो, जिसका मतलब है कि एसटीए थ्रेड के कॉल को mhallhalled किया जाएगा। ऐसा इसलिए है क्योंकि Freeआम तौर पर किसी वस्तु को इस अपेक्षा के साथ लिखा जाता है कि वह ब्लॉक हो सकती है।
  • Both। ये वर्ग लचीले हैं और वे जिस भी अपार्टमेंट में हैं, वहां से लोड करते हैं। आवश्यकताओं के दोनों सेटों को फिट करने के लिए उन्हें लिखा जाना चाहिए, हालाँकि: यदि उन्हें MTA में लोड किया जाता है, तो उन्हें समवर्ती कॉल के विरुद्ध अपनी आंतरिक स्थिति की सुरक्षा करनी चाहिए, लेकिन एसटीए में लोड होने की स्थिति में उन्हें ब्लॉक नहीं करना चाहिए।

.NET फ्रेमवर्क से, मूल रूप [STAThread]से यूआई बनाने वाले किसी भी थ्रेड पर उपयोग करें । वर्कर थ्रेड्स को MTA का उपयोग करना चाहिए, जब तक कि वे ApartmentCOM घटकों का उपयोग नहीं करने जा रहे हों , जिस स्थिति में ओवरहेड और स्केलेबिलिटी की समस्याओं से बचने के लिए STA का उपयोग करें यदि एक ही घटक को कई थ्रेड्स से कहा जाता है (जैसा कि प्रत्येक थ्रेड के लिए प्रतीक्षा करनी होगी बदले में घटक)। यदि आप प्रति घटक एक अलग COM ऑब्जेक्ट का उपयोग करते हैं, तो यह बहुत आसान है कि क्या घटक STA या MTA में है।


मुझे आपका अंतिम निष्कर्ष पसंद है, लेकिन इसके बारे में, मुझे क्या करना चाहिए अगर मैं अपने UI पर एक UserControl जोड़ना चाहता हूं जो केवल एक चीज है जो एक gif (लोडर की तरह) को पुन: पेश करने के लिए है ... मुझे इससे परेशानी हो रही है , अगर वे एक ही धागे में हैं तो जिफ नहीं ... और अगर यूआई पर एमटीए एक महान विचार है, तो आप क्या करेंगे?
योगर्टु १३'१६

2
@Yogurtu: आप COM थ्रेडिंग मॉडल के बारे में बिल्कुल क्यों चिंतित हैं? यदि आप अपने कोड में COM ऑब्जेक्ट का उपयोग कर रहे हैं तो STA / MTA निर्णय केवल प्रासंगिक है। आप UI के लिए MTA का उपयोग नहीं कर सकते - .NET के इंटर्नल का उस तरह से उपयोग करने का इरादा नहीं है। यदि आपका एनीमेशन बंद हो जाता है, तो ऐसा इसलिए है क्योंकि आपने अपने UI थ्रेड पर संदेश भेजना बंद कर दिया है। बैकग्राउंड ऑपरेशन को किसी बैकग्राउंड वर्कर में ले जाएं या छोटे चरणों में विभाजित करें। सुचारू 60Hz एनीमेशन रखने के लिए काम करने के लिए <16ms लेने की जरूरत है!
माइक डिम्मिक

"अपार्टमेंट" और एपडोमेन के बीच अंतर क्या है?
पुचैग

78

मुझे मौजूदा स्पष्टीकरण बहुत अच्छे लगते हैं। यहाँ स्पष्ट अंग्रेजी में मेरी व्याख्या है:

STA: यदि कोई थ्रेड एक COM ऑब्जेक्ट बनाता है जो STA पर सेट होता है (जब CoCreateXXX पर कॉल करते हैं तो आप एक फ्लैग पास कर सकते हैं जो COM ऑब्जेक्ट को STA मोड पर सेट करता है), तो केवल यह थ्रेड इस COM ऑब्जेक्ट (जो STA का अर्थ है - सिंगल थ्रेडेड अपार्टमेंट तक पहुँच सकता है) ), इस COM ऑब्जेक्ट पर तरीकों को कॉल करने की कोशिश कर रहा अन्य धागा हुड के तहत है जो चुपचाप COM ऑब्जेक्ट को बनाने वाले (मालिक) को संदेश देने में बदल गया है। यह बहुत हद तक इस तथ्य की तरह है कि केवल थ्रेड जिसने एक यूआई नियंत्रण बनाया है वह इसे सीधे एक्सेस कर सकता है। और यह तंत्र जटिल लॉक / अनलॉक संचालन को रोकने के लिए है।

एमटीए: यदि कोई धागा एक एमटी ऑब्जेक्ट बनाता है जो एमटीए के लिए सेट है, तो बहुत अधिक हर धागा सीधे उस पर तरीकों को कॉल कर सकता है।

यह बहुत सुंदर है। यद्यपि तकनीकी रूप से कुछ विवरण हैं जिनका मैंने उल्लेख नहीं किया था, जैसे कि 'एसटीए' पैराग्राफ में, निर्माता सूत्र को स्वयं एसटीए होना चाहिए। लेकिन यह बहुत ज्यादा है जो आपको STA / MTA / NA को समझने के लिए जानना होगा।


23

STA (सिंगल थ्रेडेड अपार्टमेंट) मूल रूप से अवधारणा है कि एक बार में केवल एक धागा आपके कोड के साथ बातचीत करेगा। आपके अपार्टमेंट में कॉल खिड़कियों के संदेशों (एक गैर-दृश्यमान) विंडो का उपयोग करके मार्श किए गए हैं। इससे कॉल को कतारबद्ध किया जा सकता है और संचालन पूरा होने की प्रतीक्षा की जा सकती है।

एमटीए (मल्टी थ्रेडेड अपार्टमेंट) वह जगह है जहां कई धागे एक ही समय में काम कर सकते हैं और थ्रेड सिक्योरिटी को संभालने के लिए डेवलपर के रूप में आप पर है।

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

अपार्टमेंट थ्रेड्स, यदि कोई थ्रेड उसी अपार्टमेंट में रहता है जिस ऑब्जेक्ट का उपयोग कर रहा है, तो यह एक अपार्टमेंट थ्रेड है। मुझे लगता है कि यह केवल एक COM अवधारणा है क्योंकि यह केवल उन वस्तुओं और धागों के बारे में बात करने का एक तरीका है जिनसे वे बातचीत करते हैं ...


19

प्रत्येक EXE जो COM या OLE नियंत्रण को होस्ट करता है, यह अपार्टमेंट स्थिति को परिभाषित करता है। अपार्टमेंट राज्य डिफ़ॉल्ट रूप से एसटीए है (और अधिकांश कार्यक्रमों के लिए एसटीए होना चाहिए)।

STA - आवश्यकता से सभी OLE नियंत्रण को STA में रहना चाहिए। STA का अर्थ है कि आपकी COM-ऑब्जेक्ट को हमेशा UI थ्रेड पर हेरफेर किया जाना चाहिए और अन्य थ्रेड्स (MFC में किसी भी UI तत्व की तरह) को पारित नहीं किया जा सकता है। हालाँकि, आपके प्रोग्राम में अभी भी कई थ्रेड हो सकते हैं।

एमटीए - आप अपने प्रोग्राम में किसी भी थ्रेड पर COM ऑब्जेक्ट को हेरफेर कर सकते हैं।


13
"STA का अर्थ है कि आपके COM-ऑब्जेक्ट को हमेशा UI थ्रेड पर हेरफेर किया जाना चाहिए" मुझे नहीं लगता कि यह बिल्कुल सही है ... यह "UI" थ्रेड पर नहीं होना चाहिए, केवल एक STA थ्रेड है जिसमें कुछ है संदेश इस पर पंप करता है क्योंकि कॉल संदेशों का उपयोग करके एक सिंक्रनाइज़ेशन करता है। यूआई धागा आमतौर पर इन आवश्यकताओं को पूरा करेगा, लेकिन यह एकमात्र संभावना नहीं है।
ब्रायन ओनील

12

मेरी समझ से, 'अपार्टमेंट' का उपयोग COM वस्तुओं को बहु-थ्रेडिंग मुद्दों से बचाने के लिए किया जाता है।

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

यदि कोई COM ऑब्जेक्ट थ्रेड-सुरक्षित है, तो उसे इसे MTA ऑब्जेक्ट घोषित करना चाहिए। MTA ऑब्जेक्ट को मल्टी-थ्रेड्स द्वारा एक्सेस किया जा सकता है।


4

कोड जो COM ऑब्जेक्ट डीएलएस कहता है (उदाहरण के लिए, मालिकाना डेटा फ़ाइलों को पढ़ने के लिए), उपयोगकर्ता इंटरफ़ेस में ठीक काम कर सकता है लेकिन एक सेवा से रहस्यमय तरीके से लटका हुआ है। इसका कारण यह है कि .Net 2.0 उपयोगकर्ता इंटरफ़ेस STA (थ्रेड-सेफ़) को ग्रहण करते हैं, जबकि सेवाएँ MTA मानती हैं (इससे पहले, सेवाएँ STA मानती थीं)। किसी सेवा में प्रत्येक COM कॉल के लिए STA थ्रेड बनाने के लिए महत्वपूर्ण ओवरहेड जोड़ सकते हैं।

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