2016-01-31 6 views
15

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

while True: 
    timeout = time_until_next_timed_event() 
    events = wait_for_events(timeout) 
    events += timed_events_until(now()) 
    for event in events: 
     event.process() 

इसका क्या अर्थ है?

उत्तर

25

मामले में यह स्पष्ट नहीं है, यह रिएक्टर कहा जाता है, क्योंकि यह प्रतिक्रिया करने के लिए बातें। लूप है यह प्रतिक्रिया करता है। एक समय में

एक पंक्ति:

while True: 

यह नहीं है वास्तव मेंwhile True; यह while not loop.stopped की तरह है। लूप को रोकने के लिए आप reactor.stop() पर कॉल कर सकते हैं, और (कुछ शट डाउन लॉजिक करने के बाद) लूप वास्तव में बाहर निकल जाएगा। लेकिन इसे उदाहरण में while True के रूप में चित्रित किया गया है क्योंकि जब आप एक लंबे समय तक चलने वाले प्रोग्राम (जैसे आप अक्सर ट्विस्ट के साथ होते हैं) लिखते हैं तो यह मानना ​​सबसे अच्छा है कि आपका प्रोग्राम या तो क्रैश हो जाएगा या हमेशा के लिए दौड़ जाएगा, और "साफ-सफाई से बाहर" नहीं है वास्तव में एक विकल्प।

 timeout = time_until_next_timed_event() 

हम इस गणना एक सा विस्तार करने के लिए थे, तो इसे और अधिक समझ बनाने सकता है:

def time_until_next_timed_event(): 
    now = time.time() 
    timed_events.sort(key=lambda event: event.desired_time) 
    soonest_event = timed_events[0] 
    return soonest_event.desired_time - now 

timed_eventsreactor.callLater साथ अनुसूचित घटनाओं की सूची है, यानी उन कार्यों को जिन्हें एप्लिकेशन ने किसी विशेष समय पर चलने के लिए कहा है।

 events = wait_for_events(timeout) 

यह पंक्ति यहां ट्विस्ट का "जादू" हिस्सा है। मैं सामान्य रूप से wait_for_events का विस्तार नहीं कर सकता, क्योंकि इसका कार्यान्वयन इस बात पर निर्भर करता है कि ऑपरेटिंग सिस्टम वांछित घटनाओं को कैसे उपलब्ध कराता है। और, यह देखते हुए कि ऑपरेटिंग सिस्टम जटिल और मुश्किल जानवर हैं, मैं इसे किसी विशिष्ट तरीके से विस्तारित नहीं कर सकता, जबकि यह आपके प्रश्न के उत्तर के लिए पर्याप्त सरल रखता है।

इस फ़ंक्शन का अर्थ क्या है इसका मतलब है, ऑपरेटिंग सिस्टम या इसके चारों ओर एक पायथन आवरण से पूछें, ब्लॉक करने के लिए, एक या अधिक ऑब्जेक्ट्स पहले इसके साथ पंजीकृत होने तक - कम से कम, बंदरगाहों की तरह सामान और स्थापित कनेक्शन, लेकिन संभावित रूप से बटन जैसी चीजें जो क्लिक हो सकती हैं - "काम के लिए तैयार" हैं। जब वे नेटवर्क से पहुंचते हैं तो काम सॉकेट से कुछ बाइट्स पढ़ रहा हो सकता है। यह कार्य नेटवर्क पर बाइट्स लिख सकता है जब एक बफर ऐसा करने के लिए पर्याप्त रूप से खाली हो जाता है। यह एक नया कनेक्शन स्वीकार कर रहा है या बंद एक का निपटान हो सकता है। इनमें से प्रत्येक संभावित घटनाएं वे कार्य हैं जो रिएक्टर आपके ऑब्जेक्ट्स पर कॉल कर सकती हैं: dataReceived, buildProtocol, resumeProducing, आदि, ताकि आप पूर्ण ट्विस्ट ट्यूटोरियल के माध्यम से जान सकें कि आप सीखेंगे।

एक बार हमें अपनी काल्पनिक "घटना" वस्तुओं की सूची मिल गई है, जिनमें से प्रत्येक का एक काल्पनिक "process" विधि है (फिर इतिहास के दुर्घटनाओं के कारण रिएक्टर में विधियों के सटीक नाम भिन्न होते हैं), फिर हम समय के साथ काम कर के लिए वापस जाओ:

 events += timed_events_until(now()) 

पहले, इस events संभालने है बस एक सार Event वर्ग है, जो एक process विधि है कि घटना के प्रत्येक विशिष्ट प्रकार को भरने के लिए की जरूरत है की एक list है।

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

अंत में,

 for event in events: 
     event.process() 

यह सिर्फ इतना है कि मुड़ चीजों की सूची यह करने के लिए है और उन्हें करता है कि माध्यम से चला जाता है। हकीकत में यह प्रत्येक घटना के आस-पास अपवादों को संभालता है, और रिएक्टर का ठोस कार्यान्वयन अक्सर Event बनाने के बजाए एक ईवेंट हैंडलर में सीधे कॉल करता है, जैसा कि पहले किया जाना आवश्यक काम रिकॉर्ड करने के लिए, लेकिन अवधारणात्मक रूप से यह केवल क्या होता है। उदाहरण के लिए event.process यहां socket.recv() और फिर yourProtocol.dataReceived पर कॉल करना हो सकता है।

मुझे आशा है कि यह विस्तारित स्पष्टीकरण आपको अपने सिर को अपने सिर में लाने में मदद करेगा। यदि आप इस पर काम करके ट्विस्ट के बारे में और जानना चाहते हैं, तो मैं आपको पर टिक्स्ड पर काम करने के लिए आईआरसी चैनल, #twisted पर चर्चा करने के लिए पर आने के लिए join the mailing list पर प्रोत्साहित करता हूं।

2

मैं विस्तृत करने की कोशिश करेंगे:

  • कार्यक्रम पैदावार को नियंत्रित करने और घटनाओं के लिए प्रतीक्षा पर सो जाओ। मुझे लगता है कि यहां सबसे दिलचस्प हिस्सा घटना है। इवेंट है: बाहरी मांग पर (नेटवर्क पैकेट प्राप्त करना, कीबोर्ड, टाइमर, विभिन्न प्रोग्राम कॉल पर क्लिक करें) प्रोग्राम को नियंत्रण प्राप्त होता है (कुछ अन्य थ्रेड या विशेष दिनचर्या में)। किसी भी तरह में नींद प्रतीक्षा_for_events बाधित हो जाती है और wait_for_events रिटर्न मिलता है।

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

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