2008-11-19 28 views
39

coroutine की अवधारणा बहुत रोचक लगती है, लेकिन मुझे नहीं पता, अगर यह वास्तविक उत्पादक वातावरण में समझ में आता है? कोरआउट के लिए उपयोग-मामले क्या हैं, जिन्हें अन्य तरीकों के साथ अधिक सुरुचिपूर्ण, सरल या अधिक कुशल हल किया जा सकता है?कोरआउट के लिए उपयोग-मामले क्या हैं?

उत्तर

18

सही कोरआउट को आपके टूलिंग से समर्थन की आवश्यकता होती है - उन्हें कंपाइलर द्वारा कार्यान्वित करने और अंतर्निहित ढांचे द्वारा समर्थित करने की आवश्यकता होती है।

कोरआउट्स का एक वास्तविक विश्व उदाहरण सी # 2.0 में प्रदान किए गए "उपज रिटर्न" कीवर्ड के साथ मिलता है, जो आपको एक विधि लिखने की अनुमति देता है जो लूपिंग के लिए कई मान देता है।

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

अधिक सामान्य स्थिति में, Coroutines का लाभ यह है कि वे समझने के लिए कुछ राज्य आधारित संगणना बहुत आसान व्यक्त करने के लिए और आसान बनाने के है । लेकिन, ऐसा करने के लिए समर्थन और टूलिंग की आवश्यकता है जो अभी तक सी # या जावा में मौजूद नहीं है।

+0

+1 यह सब "राज्य" आईएमओ के बारे में है। –

11

उत्पादक/उपभोक्ता पैटर्न को लागू करने के लिए कोरआउट्स उपयोगी हैं।

उदाहरण के लिए, पायथन ने generators नामक एक भाषा सुविधा में कोरआउट पेश किए, जिसका उद्देश्य इटरेटर के कार्यान्वयन को सरल बनाना था।

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

+0

मैं पाइथन के जेनरेटर पर टिप्पणी नहीं कर सकता, लेकिन मैंने पहले जनरेटर निर्माण का उपयोग किया है, और मुझे महान खिलौनों की समस्याओं के साथ अवधारणा निफ्टी मिली है, लेकिन वास्तविक कोडिंग में उपयोग करना बहुत कठिन है। –

+2

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

40

कुछ अच्छे उत्तर बताते हैं कि कोरआउट क्या हैं।

लेकिन वास्तविक उपयोग-मामले के लिए। एक वेब सर्वर ले लो। इसमें कई एक साथ कनेक्शन हैं, और यह उन सभी को पढ़ने और लिखना शेड्यूल करना चाहता है।

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

+5

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

+0

आपको बता सकता है कि किन कनेक्शनों पर आपके ध्यान की आवश्यकता है, यह एक अक्षम दृष्टिकोण लगता है। – xaxxon

18

उनमें से बहुत सारे, उदाहरण के लिए:

grep TODO *.c *.h | wc -l 

पाइप लाइन से ऊपर वास्तव में एक coroutine है: grep कमांड लाइन जो एक बफर करने के लिए जाने के एक दृश्य उत्पन्न करता है, wc आदेश "उन्हें खाती है"; यदि बफर भरता है, grep बफर खाली होने तक "ब्लॉक", और यदि बफर खाली है, तो wc कमांड नए इनपुट की प्रतीक्षा करता है।

कोरआउट के बारे में बात यह है कि अब वे अक्सर अधिक कठोर पैटर्न में उपयोग किए जाते हैं, जैसे कि पाइथन जनरेटर का उल्लेख किया गया है, या पाइपलाइनों के रूप में।

यदि आप उन पर अधिक देखना चाहते हैं, तो विकिपीडिया लेख देखें, खासकर coroutines और iterators पर।

+1

मैंने कभी इसके बारे में सोचा नहीं था! प्रतिभाशाली! – geckos

6

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

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

  • यदि आप विभिन्न स्थानों पर काम की इकाइयों को "उत्सर्जित" कर सकते हैं तो इनपुट-साइड कोड को व्यवस्थित/समझना आसान है।
  • आउटपुट-साइड कोड को व्यवस्थित/समझना भी आसान है अगर यह किसी नेस्टेड नियंत्रण संरचना में काम की अगली इकाई "पकड़" सकता है।

तो कोरआउट और कतार आपके निपटारे के लिए दोनों अच्छी तकनीकें हैं।

9

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

उदाहरण के लिए, एक डिवाइस पर विचार करें जिसमें एलसीडी-और-कीपैड यूजर इंटरफेस और मॉडेम है, और इसे मॉडेम का समय-समय पर कॉल करने और कीपैड पर उपयोगकर्ता के स्वतंत्रता की रिपोर्ट करने की आवश्यकता है। उपयोगकर्ता इंटरफ़ेस को लिखने का सबसे अच्छा तरीका "input_numeric_value (& CONV_SPEED_FORMAT, & conveyor_speed) जैसे कार्यों का उपयोग करना हो सकता है;" जो उपयोगकर्ता द्वारा मूल्य दर्ज करने पर वापस आ जाएगा, और संचार को संभालने का सबसे अच्छा तरीका "wait_for_carrier();" जैसे कार्यों का उपयोग कर सकता है। जो वापस आ जाएगा जब इकाई या तो जुड़ा हुआ है या निर्धारित है कि यह नहीं जा रहा है।

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

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

14

मुझे पता है कि सवाल पूछने के लगभग 5 साल बाद है, लेकिन मुझे हैरान है कि किसी ने भी उन खेलों के उपयोग के मामले का उल्लेख नहीं किया है जहां कोरआउट को अनिवार्य रूप से गणना करने के लिए बहुत कुछ उपयोग किया जाता है।

किसी गेम में एक सतत फ्रेम दर को बनाए रखने के लिए, 60 एफपीएस कहें, आपके पास प्रत्येक फ्रेम में कोड निष्पादित करने के लिए लगभग 16.6ms हैं। इसमें भौतिकी सिमुलेशन, इनपुट प्रोसेसिंग, ड्राइंग/पेंटिंग शामिल है।

मान लें कि आपकी विधि प्रत्येक फ्रेम में निष्पादित की जाती है। यदि आपकी विधि में लंबे समय तक लगते हैं और कई फ्रेम फैलते हैं, तो आप गेम लूप में शेष गणना के लिए जा रहे हैं जिसके परिणामस्वरूप उपयोगकर्ता "जंक" देखता है।

क्या कोरआउट आपको ऐसा करने देता है किसी भी समय इस गणना को टुकड़ा कर देता है ताकि यह प्रत्येक फ्रेम में थोड़ा सा चला सके।

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

+0

धन्यवाद, मैंने इसे प्राप्त करने का प्रयास करने में एक घंटे बिताए, लेकिन आपका उदाहरण वह है जिसने वास्तव में इसे मेरे लिए क्लिक किया है। –

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