पर्यवेक्षक पैटर्न का उपयोग करने की तुलना में घटनाओं के लिए मतदान कब बेहतर होगा?


41

क्या ऐसे परिदृश्य हैं जहां घटनाओं के लिए मतदान पर्यवेक्षक पैटर्न का उपयोग करने से बेहतर होगा ? मुझे मतदान का उपयोग करने का डर है और यदि कोई मुझे अच्छा परिदृश्य देता है तो मैं इसका उपयोग करना शुरू करूंगा। मैं केवल यह सोच सकता हूं कि पर्यवेक्षक का पैटर्न मतदान से बेहतर है। इस परिदृश्य को उल्टा करें:

आप एक कार सिम्युलेटर की प्रोग्रामिंग कर रहे हैं। कार एक वस्तु है। जैसे ही कार चालू होती है, आप "वूमर वूमर" साउंड क्लिप खेलना चाहते हैं।

आप इसे दो तरीकों से मॉडल कर सकते हैं:

मतदान : यह देखने के लिए कि क्या चालू है, हर सेकंड कार ऑब्जेक्ट को पोल करें। जब यह चालू हो, तो साउंड क्लिप बजाएं।

ऑब्जर्वर पैटर्न : कार को ऑब्जर्वर पैटर्न का विषय बनाएं। क्या यह सभी पर्यवेक्षकों के लिए "ऑन" ईवेंट प्रकाशित करता है जब वह स्वयं चालू होता है। एक नई ध्वनि ऑब्जेक्ट बनाएं जो कार को सुनता है। क्या यह "ऑन" कॉलबैक को लागू करता है, जो ध्वनि क्लिप बजाता है।

इस मामले में, मुझे लगता है कि पर्यवेक्षक पैटर्न जीतता है। सबसे पहले, मतदान अधिक प्रोसेसर गहन है। दूसरे, जब कार चालू होती है तो ध्वनि क्लिप तुरंत फायर नहीं करती है। मतदान की अवधि के कारण 1 सेकंड का अंतर हो सकता है।


मैं लगभग कोई परिदृश्य नहीं सोच सकता। ऑब्जर्वर पैटर्न वास्तव में वास्तविक दुनिया और वास्तविक जीवन के नक्शे हैं। इस प्रकार मुझे लगता है कि कोई भी परिदृश्य कभी भी इसका उपयोग न करने को सही ठहराएगा।
सईद नेमाटी

क्या आप उपयोगकर्ता इंटरफ़ेस घटनाओं, या सामान्य घटनाओं के बारे में बात कर रहे हैं ?
ब्रायन ओकले

3
आपका उदाहरण मतदान / अवलोकन समस्या को दूर नहीं करता है। आपने इसे निचले स्तर पर पहुंचा दिया है। आपके कार्यक्रम को अभी भी यह पता लगाने की आवश्यकता है कि कार किसी तंत्र द्वारा है या नहीं।
डंक

जवाबों:


55

कल्पना कीजिए कि आप ड्राइवर को RPM माप प्रदर्शित करने के लिए हर इंजन चक्र के बारे में सूचित करना चाहते हैं।

ऑब्जर्वर पैटर्न: इंजन प्रत्येक चक्र के लिए सभी पर्यवेक्षकों को एक "इंजन चक्र" घटना प्रकाशित करता है। एक श्रोता बनाएं जो घटनाओं को गिनता है और आरपीएम डिस्प्ले को अपडेट करता है।

मतदान: RPM प्रदर्शन इंजन चक्र काउंटर के लिए नियमित अंतराल पर इंजन से पूछता है, और तदनुसार RPM प्रदर्शन को अद्यतन करता है।

इस मामले में, पर्यवेक्षक पैटर्न शायद ढीला होगा: इंजन चक्र एक उच्च-आवृत्ति, उच्च-प्राथमिकता वाली प्रक्रिया है, आप केवल एक डिस्प्ले को अपडेट करने के लिए उस प्रक्रिया में देरी या स्टाल नहीं करना चाहते हैं। आप इंजन चक्र की घटनाओं के साथ थ्रेड पूल को फेंकना नहीं चाहते हैं।


पुनश्च: मैं वितरित प्रोग्रामिंग में अक्सर मतदान पैटर्न का उपयोग करता हूं:

ऑब्जर्वर पैटर्न: प्रोसेस ए, बी को प्रोसेस करने के लिए एक संदेश भेजता है जो कहता है "हर बार जब ई घटना होती है, तो प्रक्रिया ए को संदेश भेजें"।

पोलिंग पैटर्न: प्रक्रिया A नियमित रूप से B को संसाधित करने के लिए एक संदेश भेजता है जो कहता है कि "यदि आप ई-मेल के द्वारा पिछली बार मतदान किए जाने के बाद ई घटना करते हैं, तो मुझे एक संदेश भेजें"।

मतदान पैटर्न थोड़ा अधिक नेटवर्क लोड पैदा करता है। लेकिन पर्यवेक्षक पैटर्न में भी गिरावट आई है:

  • यदि प्रक्रिया A क्रैश हो जाती है, तो यह कभी भी बंद नहीं होगी, और B सभी अनंत काल तक इसके लिए सूचनाएं भेजने का प्रयास करेगा, जब तक कि यह विश्वसनीय रूप से दूरस्थ प्रक्रिया विफलताओं का पता नहीं लगा सकता (ऐसा करना आसान नहीं है)
  • यदि ई घटना बहुत लगातार है और / या सूचनाएं बहुत अधिक डेटा लेती हैं, तो प्रक्रिया A को अधिक ईवेंट सूचनाएँ मिल सकती हैं जो इसे संभाल सकती हैं। मतदान पैटर्न के साथ, यह मतदान को थ्रॉटल कर सकता है।
  • पर्यवेक्षक पैटर्न में, उच्च भार पूरे सिस्टम के माध्यम से "तरंग" पैदा कर सकता है। यदि आप ब्लॉकिंग सॉकेट्स का उपयोग करते हैं, तो ये तरंग दोनों तरीके से जा सकते हैं।

1
अच्छी बात। कभी-कभी प्रदर्शन के लिए यह बेहतर होता है।
फाल्कन

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

1
"जब तक यह भरोसेमंद रूप से दूरस्थ प्रक्रिया विफलताओं (ऐसा करने के लिए एक आसान बात नहीं) का पता लगा सकता है ..." मतदान को छोड़कर; पी। इस प्रकार सबसे अच्छा डिजाइन "जितना कुछ भी नहीं बदला है" प्रतिक्रिया को यथासंभव कम से कम करना है। +1, अच्छा जवाब।
pdr

2
@ जोजो: आप कर सकते हैं, हाँ, लेकिन फिर आप ऐसी पॉलिसी डाल रहे हैं जो आरपीएम काउंटर में डिस्प्ले में होनी चाहिए। शायद उपयोगकर्ता कभी-कभार आरपीएम प्रदर्शन का सटीक प्रदर्शन करना चाहता है।
ज़ैन लिंक्स

2
@ जोजो: प्रत्येक 100 वीं घटना को प्रकाशित करना एक हैक है। यह तभी अच्छी तरह से काम करता है जब ईवेंट फ़्रीक्वेंसी हमेशा सही सीमा में होती है, यदि ईवेंट को संसाधित करना इंजन के लिए बहुत लंबा नहीं होता है, अगर सभी ग्राहकों को तुलनीय सटीकता की आवश्यकता होती है। और यह आरपीएम प्रति एक मॉडुलस ऑपरेशन लेता है, जो (कुछ हजार आरपीएम मानकर) सीपीयू के लिए प्रति सेकंड कुछ मतदान संचालन की तुलना में बहुत अधिक काम है।
nikie

7

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


7

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

जब आप यूआई को अपडेट रखना चाहते हैं तो मतदान भी अच्छा है, लेकिन अंतर्निहित वस्तुएं बहुत तेजी से बदलती हैं , ऐसा नहीं है कि अधिकांश ऐप में यूआई को कुछ समय से एक सेकंड से अधिक अपडेट किया जाता है।

बशर्ते सर्वर बहुत कम लागत पर "कोई परिवर्तन नहीं" का जवाब दे सकता है और आप अक्सर बहुत अधिक मतदान नहीं करते हैं और आपके पास ग्राहकों के मतदान के लिए बहुत अधिक नहीं है, फिर वास्तविक जीवन में मतदान बहुत अच्छी तरह से काम करता है।

हालाँकि " मेमोरी " मामलों में, मैं पर्यवेक्षक पैटर्न का उपयोग करने के लिए डिफ़ॉल्ट हूं क्योंकि यह सामान्य रूप से सबसे कम काम है।


5

मतदान के कुछ नुकसान हैं, आपने मूल रूप से उन्हें अपने प्रश्न में पहले ही बता दिया था।

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

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


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

4

जब अधिसूचना से मतदान होता है, तो एक अच्छे उदाहरण के लिए, ऑपरेटिंग सिस्टम नेटवर्किंग स्टैक को देखें।

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

कई गीगाबिट ईथरनेट इंटरफेस के साथ इंटरप्ट अक्सर सीपीयू को अधिभार देगा, जिससे सिस्टम को धीमी गति से चलना चाहिए। पोलिंग के साथ नेटवर्क कार्ड बफ़र्स में पैकेट इकट्ठा करते हैं जब तक कि पोल या कार्ड्स डीएमए के माध्यम से पैकेट को मेमोरी में न लिख दें। फिर जब ऑपरेटिंग सिस्टम तैयार हो जाता है तो वह अपने सभी डेटा के लिए कार्ड का चुनाव करता है और मानक TCP / IP प्रसंस्करण करता है।

पोलिंग मोड सीपीयू को बिना बेकार रुकावट के अधिकतम प्रसंस्करण दर पर ईथरनेट डेटा एकत्र करने की अनुमति देता है। रुकावट मोड सीपीयू को पैकेट के बीच निष्क्रिय करने की अनुमति देता है जब काम इतना व्यस्त नहीं होता है।

रहस्य तब है जब एक मोड से दूसरे मोड पर स्विच करना है। प्रत्येक विधा के फायदे हैं और इसका उपयोग उचित स्थान पर किया जाना चाहिए।


2

मुझे मतदान पसंद है! क्या मैं? हाँ! क्या मैं? हाँ! क्या मैं? हाँ! क्या मैं अभी भी? हाँ! अभी का क्या? हाँ!

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

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

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

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

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

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

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

सजातीय पाश

ठीक है, मुझे एक बढ़िया टिप्पणी मिली Josh Caswellजो मेरे उत्तर में कुछ नासमझी की ओर इशारा करती है:

"थ्रेड को सूचित करने के लिए स्थिति चर का उपयोग करना पसंद है" एक घटना-आधारित / पर्यवेक्षक की तरह लगता है, मतदान नहीं

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

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

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

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

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

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

हम इस प्रकार की चीज़ के लिए लक्ष्य कर रहे हैं:

when there's work to do:
   for each thing:
       apply a very specific and uniform operation to the thing

विरोध के रूप में:

when one specific event happens:
    do something with relevant thing
in relevant thing's event:
    do some more things
in thing1's triggered by thing's event:
    do some more things
in thing2's event triggerd by thing's event:
    do some more things:
in thing3's event triggered by thing2's event:
    do some more things
in thing4's event triggered by thing1's event:
    cause a side effect which shouldn't be happening
    in this order or from this thread.

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

in thread dedicated to layout and painting:
    when there's work to do:
         for each widget that needs resizing/reposition:
              resize/reposition thing to target size/position
              mark appropriate grid cells as needing repainting
         for each grid cell that needs repainting:
              repaint cell
         go back to sleep

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

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

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


1
"थ्रेड को सूचित करने के लिए स्थिति चर का उपयोग करना पसंद है" एक घटना-आधारित / पर्यवेक्षक व्यवस्था की तरह लगता है, मतदान नहीं।
जोश कैसवेल

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

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

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

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

-4

मैं आपको पर्यवेक्षक के बारे में सोचने के वैचारिक तरीके पर अधिक जानकारी दे रहा हूं। एक परिदृश्य के बारे में सोचें जैसे कि youtube चैनल को सब्सक्राइब करना। उपयोगकर्ताओं की संख्या है जो चैनल की सदस्यता ले रहे हैं और एक बार चैनल पर कोई भी अपडेट होगा जिसमें कई वीडियो शामिल हैं ग्राहक को सूचित किया जाता है कि इस विशेष चैनल में कोई बदलाव है। इसलिए हमने निष्कर्ष निकाला कि यदि चैनल SUBJECT है जो चैनल में पंजीकृत सभी OBSERVER की सदस्यता, सदस्यता समाप्त करने और सूचित करने की क्षमता रखता है।


2
यह पूछे गए प्रश्न को संबोधित करने का प्रयास भी नहीं करता है, जब घटनाओं के लिए मतदान पर्यवेक्षक पैटर्न का उपयोग करने से बेहतर होगा। उत्तर कैसे
gnat
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.