2011-05-24 19 views
19

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


def IsPrime(numberin): 
    for n in range(2,numberin): 
     if numberin % n == 0: return(False) 
    return(True) 

(बस के लिए उदाहरण देकर स्पष्ट करना)।

अब कहें कि एक वेबसर्वर है जिसे सबमिट किए गए मान के आधार पर IsPrime को कॉल करने की आवश्यकता है। इसमें बड़े numberin के लिए लंबा समय लगेगा।

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

मैं समझता हूं कि यह कैसे करें यदि IsPrime कार्यक्षमता किसी अन्य वेबसर्वर से आई है, जिस पर मेरा वेबसर्वर एक स्थगित GetPage करेगा, लेकिन क्या होगा यदि यह सिर्फ एक स्थानीय कार्य है?

यानी, किसी भी तरह से IsPrime को दो कॉल के बीच समय-साझा किया जा सकता है, या इसके लिए एक नए धागे के स्पष्ट आमंत्रण की आवश्यकता होगी?

या, क्या IsPrime लूप को छोटे लूप की श्रृंखला में घुमाया जाना चाहिए ताकि नियंत्रण को रिएक्टर को तेजी से वापस किया जा सके?

या कुछ और?

+3

जब आपके पास कोई ऐसा कार्य होता है जो वास्तव में बहुत समय लेता है, उदाहरण के लिए। यह "अवरुद्ध" है, आप इसे थ्रेड में चलाने के लिए 'deferToThread()' का उपयोग कर सकते हैं: http://twistedmatrix.com/documents/11.0.0/api/twisted.internet.threads.deferToThread.html –

+1

या ट्विस्ट की प्रक्रिया समर्थन: http://twistedmatrix.com/documents/current/core/howto/process.html –

+0

हां, मैंने एक [बहुत ही समान प्रश्न] लिखा है (http://stackoverflow.com/questions/5719782/confusion-about-cpu हाल ही में Node.js के लिए -इनेंट-कोड-इन-नोड-जेएस)। यह देखने में रूचि है कि समाधान मुड़ने में क्या हैं। – YXD

उत्तर

26

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

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

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

ट्विस्ट थ्रेड और प्रक्रियाओं से निपटने के लिए कई एपीआई भी प्रदान करता है। यह उपयोगी हो सकता है अगर यह स्पष्ट नहीं है कि कैसे काम में नौकरी तोड़ना है। थ्रेड पूल में एक (थ्रेड-सुरक्षित!) फ़ंक्शन चलाने के लिए आप deferToThread का उपयोग कर सकते हैं। सुविधाजनक रूप से, यह एपीआई एक Deferred देता है जो अंततः फ़ंक्शन के वापसी मूल्य (या Failure के साथ फ़ंक्शन को अपवाद उठाता है) के साथ आग लग जाएगा।ये डिफर्ड किसी अन्य की तरह दिखते हैं, और जहां तक ​​उनका उपयोग करने वाले कोड का संबंध है, यह getPage जैसे कॉल से वापस आ सकता है - एक ऐसा फ़ंक्शन जो अतिरिक्त थ्रेड का उपयोग नहीं करता है, केवल गैर-अवरुद्ध I/O और ईवेंट हैंडलर।

चूंकि पाइथन एक ही प्रक्रिया में एकाधिक सीपीयू-बाउंड थ्रेड चलाने के लिए आदर्श रूप से उपयुक्त नहीं है, इसलिए ट्विस्ट भी बाल प्रक्रियाओं के साथ लॉन्च करने और संचार करने के लिए एक गैर-अवरोधक API प्रदान करता है। आप जीआईएल को धीमा करने के बारे में चिंता किए बिना अतिरिक्त CPUs या कोर का लाभ उठाने के लिए ऐसी प्रक्रियाओं की गणना को ऑफ़लोड कर सकते हैं, कुछ ऐसा नहीं जो न तो चंकिंग रणनीति और न ही थ्रेडिंग दृष्टिकोण प्रदान करता है। ऐसी प्रक्रियाओं से निपटने के लिए निम्नतम स्तर API reactor.spawnProcess है। Ampoule भी है, एक पैकेज जो आपके लिए एक प्रोसेस पूल का प्रबंधन करेगा और प्रक्रियाओं के लिए deferToThread पर एनालॉग प्रदान करेगा, deferToAMPProcess

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