राज्य मशीनें बनाम धागे


24

एलन कॉक्स ने एक बार कहा था "एक कंप्यूटर एक राज्य मशीन है। थ्रेड्स उन लोगों के लिए हैं जो राज्य मशीनों को प्रोग्राम नहीं कर सकते हैं"।
चूंकि एलन से पूछना सीधे तौर पर मुझे विनम्र करने का विकल्प नहीं है, इसलिए मैं यहां पूछना चाहता हूं: कोई व्यक्ति केवल जावा और स्टेट मशीन का उपयोग करके उच्च-स्तरीय भाषा में मल्टी-थ्रेडिंग कार्यक्षमता कैसे प्राप्त करता है? उदाहरण के लिए, क्या होगा यदि प्रदर्शन करने के लिए 2 गतिविधियाँ हैं (गणना और I / O करने के लिए) और एक गतिविधि अवरुद्ध हो सकती है?
क्या उच्च स्तर की भाषाओं में मल्टी-थ्रेडिंग के लिए "राज्य-मशीन केवल" व्यवहार्य विकल्प का उपयोग कर रहा है?


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

10
एलन एक ओएस कर्नेल डेवलपर था; यह उनका अधिवास था । तो उनका उद्धरण उस संदर्भ में लिया जाना चाहिए। वह 'मेटल के खिलाफ' प्रोग्रामिंग कर रहा होगा, जहां इस तरह के मॉडल का उपयोग करना अधिक समझ में आता है। एक बार जब ओएस हार्डवेयर को दूर कर देता है, और इसकी आंतरिक आबादी (कि "एक कंप्यूटर एक राज्य मशीन है ...") आपके पास अन्य मॉडल का उपयोग करने में सक्षम होने का अवसर और लाभ है जो आपके डोमेन में अधिक समझ में आता है । लगभग हर खेल राज्य मशीनों का भारी उपयोग करता है ।
स्टीवन एवर्स

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

2
"लेकिन [धागा] अमूर्त आपको बहुत सरल और कम त्रुटि-प्रवण इंटरफ़ेस प्रदान करता है।" वह झूठा मालूम पड़ता है। थ्रेड-सेफ्टी गलत पाने वालों की संख्या इंगित करती है कि यह त्रुटियों का कारण बनता है।
S.Lott

1
यहाँ बहुत सारी टिप्पणियाँ और उत्तर उद्धरण की व्याख्या करते हैं जो सामान्य रूप से बहु-विरोधी होने के रूप में हैं; मेरा मानना ​​है कि एलन कॉक्स केवल विरोधी धागे हैं और कई प्रक्रियाओं का उपयोग करने की वकालत करेंगे, ताकि लोग ऐसे लक्ष्यों को प्राप्त कर सकें जिनके लिए लोग धागे का उपयोग करते हैं। ध्यान रखें कि वह एक यूनिक्स हैकर है: फोर्क एफटीडब्ल्यू। मुझे सीधे उद्धरण पर उनसे कोई टिप्पणी नहीं मिली है, लेकिन यहाँ लिनक्स कर्नेल मेलिंग सूची से लैरी मैकविओय से एक है जो इस दिशा में जाता है: lkml.indiana.edu/hypermail/linux/kernel/0106.2/0405.html
मार्टिन बी

जवाबों:


25

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

सिंगल-कोर कंप्यूटर पर, वास्तव में "एक ही समय में" कुछ भी नहीं होता है। यह सब सिर्फ interleaved निष्पादन है।

Interleaving प्राप्त करने के कई, कई तरीके हैं। अनेक।

मान लें कि आपके पास एक सरल दो-थ्रेडेड प्रक्रिया है जो एक साधारण लॉक का उपयोग करती है ताकि दोनों धागे एक सामान्य चर को लिख सकें। आपके पास कोड के छह ब्लॉक हैं।

  • T1- पहले ताला
  • T1- लॉक के साथ
  • T1- लॉक होने के बाद
  • T2- पहले ताला
  • T2- लॉक के साथ
  • T2- लॉक के बाद

[यह एक लूप में हो सकता है या अधिक ताले या जो कुछ भी हो सकता है। यह सब अधिक लंबा है, अधिक जटिल नहीं है।]

T1 के चरणों को क्रम में चलना चाहिए (T1-इससे पहले, T1-with, T1-after) और T2 के चरणों को क्रम में चलना चाहिए (T2-इससे पहले, T2-with, T2-after)।

"इन-ऑर्डर" बाधा के अलावा, इनका किसी भी तरह से अंतःक्रिया किया जा सकता है। किसी भी तरह। वे ऊपर सूचीबद्ध के रूप में चलाए जा सकते हैं। एक अन्य मान्य आदेश है (T1- पहले, T2- पहले, T2- ताला, T1- ताला, T2-after, T1-after)। बहुत सारे मान्य आदेश हैं।

रुकिए।

यह सिर्फ छह राज्यों वाली एक राज्य मशीन है।

यह एक गैर-नियतात्मक परिमित राज्य ऑटोमेटा है। T2-xxx राज्यों के साथ T1-xxx राज्यों का क्रम अनिश्चित है, और कोई फर्क नहीं पड़ता। तो ऐसे स्थान हैं जहां "अगला राज्य" एक सिक्का टॉस है।

उदाहरण के लिए, जब FSM शुरू होता है, T1- पहले या T2- पहले दोनों वैध पहले राज्य होते हैं। सिक्का उछालो।

मान लीजिए कि यह टी -1 से पहले आया था। वो करें। जब ऐसा किया जाता है, तो T1-with और T2- पहले के बीच एक विकल्प होता है। सिक्का उछालो।

एफएसएम में प्रत्येक चरण में दो विकल्प होंगे (दो धागे - दो विकल्प) और एक सिक्का टॉस यह निर्धारित कर सकता है कि किस विशिष्ट राज्य का पालन किया जाता है।


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

5
एक मल्टी-कोर मशीन शेड्यूलिंग को और अधिक जटिल बनाती है। हालाँकि, सभी कोर एक एकल आम मेमोरी में लिखते हैं, इसलिए दो कोर के बीच मेमोरी राइट ऑर्डर करने का अर्थ है कि - अनिवार्य रूप से - हम मेमोरी मेमोरी के इंटरलेक्स्ड निष्पादन पर वापस आते हैं। OS कोर का शोषण करता है और JVM इसका लाभ उठाता है। इसके बारे में दो बार सोचने की जरूरत नहीं है।
S.Lott

9

अवरुद्ध कार्य लिखना उन लोगों के लिए है जो राज्य मशीन नहीं बना सकते हैं;)

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

आप एक राज्य मशीन में अवरुद्ध कार्यों का उपयोग नहीं कर सकते हैं (कम से कम एक "फ्रीज" करने की अनुमति नहीं दी जा सकती है)।

और हाँ, राज्य मशीन का उपयोग करना एक व्यवहार्य विकल्प है। रियल टाइम सिस्टम में, यह एकमात्र विकल्प है, मशीन के लिए एक ढांचा प्रदान करने वाला सिस्टम। थ्रेड्स और ब्लॉकिंग फ़ंक्शन का उपयोग करना "आसान तरीका है", क्योंकि आमतौर पर ब्लॉकिंग फ़ंक्शन के लिए एक कॉल राज्य मशीन में लगभग 3-4 राज्यों को बदल देता है।


एक एकल-संदर्भ-निष्पादन कार्यक्रम में एक कोड पृष्ठ की गलती मौलिक रूप से वास्तव में अवरुद्ध है। परिभाषा के अनुसार, कोड जिसमें निष्पादन का एक भी संदर्भ है, आगे की प्रगति नहीं कर सकता जब तक कि प्रवाह में कोड का अगला हिस्सा उपलब्ध न हो।
डेविड श्वार्ट्ज

1
@ डेविड Schwartz: सच है, यह मौलिक रूप से अवरुद्ध है; लेकिन यह एक 'ऑपरेशन' नहीं है क्योंकि यह कुछ ऐसा नहीं है जो अवरुद्ध कोड करता है, यह ऐसा कुछ है जो इसके साथ होता है।
जेवियर

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

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

1
@Mar: ... या एक नियतकालिक स्वैप एल्गोरिदम का उपयोग करें जो आवश्यक डेटा प्राप्त करने से पहले आवश्यक हो।
एसएफ।

9

केवल एक धागे और राज्य मशीन का उपयोग करके जावा जैसी उच्च-स्तरीय भाषा में मल्टी-थ्रेडिंग कार्यक्षमता कैसे प्राप्त की जा सकती है? उदाहरण के लिए, क्या होगा यदि प्रदर्शन करने के लिए 2 गतिविधियाँ हैं (गणना और I / O करने के लिए) और एक गतिविधि अवरुद्ध हो सकती है?

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

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

क्या उच्च स्तर की भाषाओं में मल्टी-थ्रेडिंग के लिए "राज्य-मशीन केवल" व्यवहार्य विकल्प का उपयोग कर रहा है?

व्यवहार्य? ज़रूर। साने? कभी कभी। चाहे आप थ्रेड्स का उपयोग करें या किसी प्रकार का होम-ब्रूएड कोऑपरेटिव मल्टीटास्किंग (जैसे, स्टेट मशीन) उस ट्रेडऑफ़ पर निर्भर करते हैं जिसे आप बनाने के इच्छुक हैं।

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

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

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

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

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


2

क्या होगा अगर प्रदर्शन करने के लिए 2 गतिविधियाँ हैं (गणना करना और I / O करना) और एक गतिविधि अवरुद्ध कर सकती है?

वैसे मैं ईमानदारी से सोच भी नहीं सकता कि बिना धागे के I / O को ब्लॉक करना कैसे सम्भव है। इसे आफ्टर ब्लॉकिंग कहा जाता है क्योंकि कोड जो इसे लागू करता है wait

मूल कॉक्स ईमेल (नीचे) के मेरे पढ़ने के अनुसार, वह बताते हैं कि थ्रेडिंग अच्छी तरह से पैमाने पर नहीं है। मेरा मतलब है, क्या होगा अगर 100 आई / ओ अनुरोध हैं? 1000? 10000? कॉक्स इंगित कर रहा है कि बड़ी संख्या में धागे होने से गंभीर समस्याएं हो सकती हैं:

प्रेषक: एलन कॉक्स (alan@lxorguk.ukuu.org.uk)
दिनांक: शुक्र जनवरी २१ २००० - १३:३३:५०

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

यह आपकी चिंता का कम से कम है। 1000 थ्रेड्स 8Mb कर्नेल स्टैक हैं, और यह सुनिश्चित करने के लिए कार्यों का पर्याप्त स्विचिंग है कि आप अपने अधिकांश कैश को बंद कर सकते हैं। कंप्यूटर एक राज्य मशीन है। थ्रेड्स उन लोगों के लिए हैं जो राज्य मशीनों को प्रोग्राम नहीं कर सकते।

बहुत सारे मामले हैं लिनक्स निश्चित रूप से स्थिति को अतुल्यकालिक ब्लॉक I / O में विशेष रूप से मदद नहीं कर रहा है।

एलन

स्रोत: पुन: आईबीएम (लिनक्स-कर्नेल मेलिंग सूची अभिलेखागार) द्वारा फैले लिनक्स कर्नेल का दिलचस्प विश्लेषण


1
  • सिद्धांत रूप में, यह सच है। वास्तविक जीवन में, धागे ऐसे राज्य मशीन को प्रोग्राम करने के लिए उपयोग किए जाने वाले एक कुशल अमूर्त हैं। वे इतने कुशल हैं कि उन्हें स्टेटचैट्स और पेट्री नेट को प्रोग्राम करने के लिए उपयोग किया जा सकता है (यानी, समानांतर व्यवहार, जहां राज्य मशीनें मूल रूप से अनुक्रमिक हैं)।

  • राज्य मशीनों के साथ समस्या दहनशील विस्फोट है। 4 जी रैम वाले कंप्यूटर की संख्या 2 ^ (2 ^ 32) राज्यों (2T डिस्क ड्राइव की गिनती नहीं) है।

  • एक आदमी के लिए जिसका एकमात्र उपकरण एक हथौड़ा है, हर समस्या नाखून की तरह दिखती है।


1

थ्रेड्स दो मामलों में एकमात्र विकल्प हैं:

  • मेमोरी सेपरेशन के बिना कई कोर का उपयोग करने के लिए।
  • बाहरी कोड से निपटने के लिए जो ब्लॉक करता है।

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

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


1
दोनों दुनिया का सबसे अच्छा: थ्रेड्स में छोटी, अवरुद्ध राज्य मशीनें बहुत सरल अनुप्रयोग कोड बनाती हैं। और धागे अगर आप उन्हें मिल गया है तो अच्छी तरह से कोर को विभाजित करते हैं। अगर सब कुछ कम से कम दो कोर नहीं है, तो यह जल्द ही होगा। 2012 तक आने वाले क्वाड कोर आर्म आधारित फोन।
टिम विलिसक्राफ्ट

0

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

while (true) {
    switch (event) {
        case ButtonPressed:
        ...
        case MachineIsBurning:
        ....
    }
}

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

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

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

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


0

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

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


0

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

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

कुछ मामलों में, एक राज्य मशीन एक बेहतर विकल्प होगा - मैं अब एम्बेडेड प्रकार के सामान के बारे में सोच रहा हूं जहां कुछ राज्य मशीन पैटर्न का उपयोग किया जाता है, और बार-बार और अधिक औपचारिक तरीके से उपयोग किया जाता है (यानी उचित इंजीनियरिंग :))

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

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


2
राज्य मशीनें जटिल नहीं हैं! जटिल राज्य मशीनें जटिल हैं, लेकिन इसलिए सभी जटिल प्रणालियां हैं: ओ)
MaR

2
-1 के लिए "कोशिश मत करो"। सबसे बुरी सलाह जो आप दे सकते हैं।
जेवियर

1
-1 "कोशिश मत करो"? यह सिर्फ मूर्खता है। मैं आपके दावे को भी चुनौती दूंगा कि राज्य मशीनें कठिन हैं। एक बार जब आप हीरारचल फ़ज़ी स्टेट मशीन की तरह कुछ कर लेते हैं ... तो हाँ, यह थोड़ा अधिक जटिल है। लेकिन एक साधारण राज्य मशीन? यह बहुत बुनियादी चीजें हैं जो हर 2 साल में सीखीं जब मैं स्कूल में था।
स्टीवन एवर्स

मुझे 'बिट ट्राई' न करें ...
gbjbaanb

0

धागे के बजाय एक उचित राज्य मशीन के उपयोग का अच्छा उदाहरण: nginx बनाम apache2। आम तौर पर आप यह मान सकते हैं कि nginx एक धागे में सभी कनेक्शनों को संभालता है, Apache2 प्रति कनेक्शन एक धागा बनाता है।

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

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