अपने उद्देश्यों के लिए माइक्रोपायथॉन की संभावनाओं का अध्ययन करते हुए, मैं एसिंको लाइब्रेरी के कार्यान्वयन में से एक आया और, लाइब्रेरी के लेखक, पिटर हिंच के साथ एक संक्षिप्त पत्राचार के बाद, मुझे एहसास हुआ कि मुझे सिद्धांतों, बुनियादी अवधारणाओं और अतुल्यकालिक प्रोग्रामिंग विधियों का उपयोग करने की विशिष्ट त्रुटियों को समझने की आवश्यकता है। इसके अलावा, शुरुआती के लिए अनुभाग सिर्फ मेरे लिए है।यह गाइड
asyncio के साथ अनुभव के विभिन्न स्तरों वाले उपयोगकर्ताओं के लिए है, जिसमें शुरुआती लोगों के लिए एक विशेष खंड भी शामिल है।
सामग्री0. परिचय0.1 .___ खाली डिवाइस (हार्डवेयर) पर
uasyncio इंस्टॉल करना
1. संयुक्त कार्यक्रम के निष्पादन के लिए योजना1.1 .___ मॉड्यूल
2. uasyncio पुस्तकालय2.1 .___ कार्यक्रम संरचना: घटना प्रसंस्करण चक्र
२.२
योजना में भाग लेने के लिए 2.2.1
2.2.2 .______
फ़ंक्शन कॉलबैक ( कॉलबैक ) शुरू करना2.2.3 .______
नोट: संबंधित तरीकों के रूप में कोरटाइन। वापसी का मान।2.3 .___ विलंब
3. तुल्यकालन और इसकी कक्षाएं3.1 .___ लॉक
लॉक3.1.1 .______
लॉक और टाइमआउट3.2 .___
घटना3.2.1 .______ घटना
मूल्य३.३ .___ बैरियर
बैरियर३.४ .___
सेमफोर३.४.१.______
लिमिटेड सेमाफोर3.5 .___ कतार से
कतार3.6 .___ अन्य सिंक क्लासेस
4. वर्ग विकास asyncio के लिए4.1 .___ वेट का उपयोग करने वाली कक्षाएं
4.1.1 .______
संदर्भ प्रबंधकों में उपयोग करें4.1.2 .______
कोरटाइन में प्रतीक्षा करें4.2 .___ अतुल्यकालिक Iterators
4.3 .___ अतुल्यकालिक प्रसंग प्रबंधक
5. टाइमआउट और कार्य रद्द करने के कारण अपवाद5.1 .___ अपवाद
5.2 .___ समय समाप्ति के कारण अपवाद और कार्यों को रद्द करने के कारण
5.2.1 .______
कार्य रद्द करें5.2.2 .______
टाइमआउट के साथ कोराटाइन6. हार्डवेयर उपकरणों के साथ सहभागिता6.1 .___ सिंक समस्याएं
6.2 .___ मतदान उपकरण कोरटाइन के साथ
6.3 .___ स्ट्रीमिंग इंजन का उपयोग करना
6.3.1 .______
UART ड्राइवर उदाहरण6.4 .___ ड्राइवर विकास एक स्ट्रीमिंग डिवाइस के लिए
6.5 .___ पूर्ण उदाहरण: IR रिमोट कंट्रोल रिसीवर के लिए
aremote.py ड्राइवर।
6.6 .___ तापमान और आर्द्रता सेंसर HTU21D के लिए ड्राइवर।
7. टिप्स और ट्रिक्स7.1 .___ प्रोग्राम फ्रीज
7.2 .___
uasyncio राज्य बचाता है
7.3 .___ कचरा संग्रह
7.4 .___ परीक्षण
7.5 .___ सामान्य त्रुटि। इसे खोजना मुश्किल हो सकता है।
7.6 .___ सॉकेट (
सॉकेट ) का उपयोग करके प्रोग्रामिंग करना
7.6.1 .______
WiFi समस्याएँ7.7 .___ इवेंट लूप कंस्ट्रक्टर के तर्क
8. शुरुआती के लिए नोट्स8.1 .___ समस्या 1: इवेंट लूप्स
8.2 .___ समस्या 2: लॉकिंग विधियाँ
8.3 .___
uasyncio दृष्टिकोण
8.4 .___
uasyncio में योजना
8.5 .___ सहयोगी, थ्रेड-आधारित शेड्यूलिंग (
_थ्रेड ) क्यों नहीं?
8.6 .___ सहभागिता
8.7 .___
मतदान0. परिचयइस दस्तावेज़ में से अधिकांश अतुल्यकालिक प्रोग्रामिंग के साथ कुछ परिचित हैं। शुरुआती लोगों के लिए, एक परिचय धारा 7 में पाया जा सकता है।
MicroPython के लिए
uasyncio लाइब्रेरी में
asyncio Python लाइब्रेरी का सबसेट शामिल है और इसका उपयोग माइक्रोकंट्रोलर्स पर करने के लिए किया जाता है। जैसे, यह रैम की एक छोटी राशि लेता है और शून्य रैम आवंटन के साथ संदर्भों को जल्दी से स्विच करने के लिए कॉन्फ़िगर किया गया है।
यह दस्तावेज़ हार्डवेयर उपकरणों के लिए ड्राइवर बनाने पर जोर देने के साथ
उस्सिनसियो के उपयोग का वर्णन करता है।
लक्ष्य ड्राइवरों को डिजाइन करना है ताकि एप्लिकेशन काम करना जारी रखे, जबकि ड्राइवर डिवाइस से प्रतिक्रिया की प्रतीक्षा कर रहा है। इसी समय, एप्लिकेशन अन्य घटनाओं और उपयोगकर्ता इंटरैक्शन के लिए संवेदनशील रहता है।
Asyncio के अनुप्रयोग का एक अन्य महत्वपूर्ण क्षेत्र नेटवर्क प्रोग्रामिंग है: इंटरनेट पर आप इस विषय पर पर्याप्त जानकारी पा सकते हैं।
ध्यान दें कि
MicroPython न्यूनतम
पायथन 3.5 ऐड-ऑन के साथ
पायथन 3.4 पर आधारित है। नीचे के रूप में छोड़कर, 3.4 से अधिक पुराने
asyncio संस्करणों के कार्यों का समर्थन नहीं किया जाता है। यह दस्तावेज़ इस सबसेट में समर्थित सुविधाओं को परिभाषित करता है।
इस गाइड का उद्देश्य
CPython V3.5 और उच्चतर के साथ संगत एक प्रोग्रामिंग शैली पेश करना है।
0.1 एक खाली डिवाइस (हार्डवेयर) पर uasyncio स्थापित करेंयह फर्मवेयर
MicroPython V1.11 या बाद के
संस्करण का उपयोग करने के लिए अनुशंसित है। कई प्लेटफार्मों पर, स्थापना की आवश्यकता नहीं है क्योंकि विधानसभा में
uasyncio पहले
से ही संकलित है। जाँच करने के लिए, केवल REPL में टाइप करें
import uasyncio
निम्न निर्देश मामलों को कवर करते हैं जब मॉड्यूल पूर्व-स्थापित नहीं होते हैं।
कतारों और
सिंक्रो मॉड्यूल वैकल्पिक हैं, लेकिन यहां दिए गए उदाहरणों को चलाने के लिए आवश्यक हैं।
इंटरनेट से जुड़ी डिवाइसइंटरनेट से जुड़े उपकरण और फर्मवेयर V1.11 या बाद के संस्करण पर, आप बिल्ट-
अप अप संस्करण का उपयोग करके इंस्टॉल कर सकते हैं। यह सुनिश्चित करना कि डिवाइस आपके नेटवर्क से जुड़ा है:
import upip upip.install ( 'micropython-uasyncio' ) upip.install ( 'micropython-uasyncio.synchro' ) upip.install ( 'micropython-uasyncio.queues' )
Upip से त्रुटि संदेश बहुत उपयोगी नहीं
हैं । यदि आपको कोई अयोग्य त्रुटि मिलती है, तो इंटरनेट कनेक्शन फिर से जांचें।
इंटरनेट कनेक्शन के बिना हार्डवेयर ( micropip )यदि आपके डिवाइस में इंटरनेट कनेक्शन नहीं है (उदाहरण के लिए,
Pyboard V1.x ), तो सबसे आसान तरीका यह है कि आप अपनी पसंद की निर्देशिका के लिए कंप्यूटर पर
micropip.py की स्थापना शुरू करें, और फिर परिणामी निर्देशिका संरचना को लक्ष्य डिवाइस में कॉपी करें।
Micropip.py उपयोगिता
पायथन 3.2 या बाद के संस्करण पर और लिनक्स, विंडोज, और OSX पर चलती है। अधिक जानकारी
यहां पाई जा सकती
है ।
विशिष्ट कॉल:
$ micropip.py install -p ~/rats micropython-uasyncio $ micropip.py install -p ~/rats micropython-uasyncio.synchro $ micropip.py install -p ~/rats micropython-uasyncio.queues
इंटरनेट कनेक्शन के बिना एक उपकरण (प्रतिलिपि स्रोत)यदि आप
micropip.py का उपयोग नहीं करते हैं, तो फ़ाइलों को स्रोत से कॉपी किया जाना चाहिए। निम्न निर्देश वर्णन करते हैं कि लक्ष्य डिवाइस पर न्यूनतम संख्या में फ़ाइलों की प्रतिलिपि कैसे
बनाई जाए, साथ ही मामला जब
uasyncio को कब्जे वाली जगह को कम करने के लिए बाइट कोड के रूप में संकलित विधानसभा में संकुचित करने की आवश्यकता होती है। आधिकारिक फर्मवेयर के साथ संगत नवीनतम संस्करण के लिए, फ़ाइलों को आधिकारिक
माइक्रोप्रोथेन-लिबसाइट से कॉपी किया जाना चाहिए।
कमांड के साथ लाइब्रेरी को कंप्यूटर पर क्लोन करें
$ git clone https://github.com/micropython/micropython-lib.git
टारगेट डिवाइस पर,
uasyncio डायरेक्टरी (
लिबास डायरेक्टरी में वैकल्पिक) बनाएं और उसमें निम्नलिखित फाइलों को कॉपी करें:
• uasyncio / uasyncio / __ init__.py
• uasyncio.core / uasyncio / core.py
• uasyncio.synchro / uasyncio / synchro.py
• uasyncio.queues / uasyncio / queues.py
इन
uasyncio मॉड्यूल को
utecyncio निर्देशिका और इसकी सामग्री को
मॉड्यूल निर्देशिका के बंदरगाह में रखकर और सामग्री को
फिर से
जमा करके
बाइटेकोड में संपीड़ित किया जा सकता है।
1. संयुक्त योजनाकई कार्यों के संयुक्त निष्पादन की तकनीक व्यापक रूप से एम्बेडेड सिस्टम में उपयोग की जाती है, जो थ्रेडिंग (
_थ्रेड ) शेड्यूलिंग की तुलना में कम ओवरहेड प्रदान करती है, वास्तव में अतुल्यकालिक धागे से जुड़े कई नुकसानों से
बचती है ।
1.1 मॉड्यूलनिम्नलिखित मॉड्यूल की एक सूची है जो लक्ष्य डिवाइस पर चल सकती है।
पुस्तकालयों1.
asyn.py लॉक, ईवेंट, बैरियर, सेमाफोर, बाउंडेडसेमाफोर, कंडीशन प्रदान करता है
, सिंक्रोनाइज़ेशन प्राइमेटिव
इकट्ठा करता है ।
NamedTask और
रद्द करने योग्य कक्षाओं के माध्यम से कार्यों को रद्द करने के लिए समर्थन प्रदान करता है।
2.
aswitch.py स्विच और बटन
बाँधने के लिए कक्षाओं का प्रतिनिधित्व करता है, साथ ही बार-बार देरी की संभावना के साथ एक प्रोग्राम ऑब्जेक्ट। बटन स्विच का एक सामान्यीकरण है जो भौतिक स्थिति के बजाय एक तार्किक प्रदान करता है, साथ ही घटनाओं को एक डबल और लंबे प्रेस द्वारा ट्रिगर किया जाता है।
डेमो कार्यक्रमपहले दो सबसे उपयोगी होते हैं क्योंकि वे
Pyboard हार्डवेयर तक पहुँचते समय दृश्यमान परिणाम देते हैं।
- aledflash.py चार पायबोर्ड संकेतक 10 सेकंड के लिए अतुल्यकालिक रूप से चमकता है । Uasyncio का सबसे सरल प्रदर्शन। इसे चलाने के लिए आयात करें।
- apoll.py डिवाइस ड्राइवर Pyboard एक्सेलेरोमीटर के लिए। डिवाइस को क्वेरी करने के लिए कोरटाइन के उपयोग को दर्शाता है। 20 एस के लिए काम करता है। इसे चलाने के लिए आयात करें। Pyboard V1.x की आवश्यकता है
- एस्ट्रिच मॉड्यूल के लिए astests.py टेस्ट / डेमो प्रोग्राम।
- asyn_demos.py कार्य को रद्द करने का सरल डेमो।
- roundrobin.py परिपत्र योजना का प्रदर्शन। इसके अलावा प्रदर्शन की योजना के लिए बेंचमार्क।
- प्रतीक्षा के साथ वर्ग का प्रदर्शन। एक डिवाइस ड्राइवर को लागू करने का एक तरीका है जो एक इंटरफ़ेस को पोल करता है।
- चेनहोम पाइथन प्रलेखन से नकल की गई। Coroutine श्रृंखला प्रदर्शन।
- aqtest.py uasyncio लाइब्रेरी की कतार वर्ग का प्रदर्शन।
- NEC IR प्रोटोकॉल के लिए aremote.py उदाहरण डिवाइस ड्राइवर।
- auart.py, Pyboard UART के माध्यम से इनपुट-आउटपुट स्ट्रीमिंग का प्रदर्शन।
- auart_hd.py आधे-द्वैध प्रोटोकॉल का उपयोग करके डिवाइस के साथ संवाद करने के लिए Pyboard UART का उपयोग करना। उपकरणों के लिए उपयुक्त, उदाहरण के लिए, एटी मॉडेम कमांड सेट का उपयोग करना।
- I / O स्ट्रीमिंग का उपयोग करके रीडर / लेखक डिवाइस का iorw.py प्रदर्शन।
परीक्षण कार्यक्रम- asyntest.py टेस्ट के लिए सिंक्रोनाइज़ेशन क्लासेस asyn.py.
- cantest.py नौकरी रद्द करने का परीक्षण।
उपयोगिता1.
check_async_code.py उपयोगिता विशिष्ट कोडिंग त्रुटियों का पता लगाने के लिए
Python3 में लिखी गई है जिसे खोजना मुश्किल हो सकता है। खंड 7.5 देखें।
नियंत्रणबेंचमार्क निर्देशिका में
uasyncio अनुसूचक की जाँच और विशेषता के लिए स्क्रिप्ट शामिल हैं।
2. uasyncio पुस्तकालयAsyncio अवधारणा कई कार्यों के संयुक्त निष्पादन के लिए नियोजन के संगठन पर आधारित है, जिसे इस दस्तावेज़ में
कॉरआउट कहा जाता
है ।
2.1 कार्यक्रम संरचना: ईवेंट लूपनिम्नलिखित उदाहरण पर विचार करें:
import uasyncio as asyncio async def bar (): count = 0, while True : count + = 1 print ( count ) await asyncio.sleep ( 1 )
कार्यक्रम निष्पादन तब तक जारी रहता है, जब तक
लूप .run_forever नहीं कहलाता । इस बिंदु पर, निष्पादन को अनुसूचक द्वारा नियंत्रित किया जाता है।
Loop.run_forever के बाद की लाइन कभी भी निष्पादित नहीं होगी। शेड्यूलर
बार कोड निष्पादित करता है क्योंकि इसे
लूप में पंक्तिबद्ध किया गया है। इस तुच्छ उदाहरण में, केवल एक coroutine
बार है । यदि कोई अन्य होते हैं, तो शेड्यूलर उन्हें उस अवधि के दौरान निष्पादित करेगा जब
बार को रोक दिया गया था।
अधिकांश एम्बेडेड अनुप्रयोगों में एक निरंतर ईवेंट लूप होता है। एक इवेंट लूप को इस तरह से भी शुरू किया जा सकता है जो
run_until_complete इवेंट लूप विधि का उपयोग करके पूरा करने की अनुमति देता है; यह मुख्य रूप से परीक्षण में उपयोग किया जाता है। उदाहरण
astests.py मॉड्यूल में पाए जा सकते हैं।
इवेंट लूप आवृत्ति एक एकल ऑब्जेक्ट है जिसे पहली कॉल
asyncio.get_event_loop () द्वारा दो वैकल्पिक पूर्णांक तर्कों के साथ दो
कतारों में कोरआउट की संख्या को दर्शाता है - प्रारंभ और प्रतीक्षा। आमतौर पर, दोनों तर्कों का एक ही मूल्य होगा, कम से कम आवेदन में एक साथ निष्पादित कोराउटीन की संख्या के बराबर। आमतौर पर, 16 का डिफ़ॉल्ट मान पर्याप्त होता है। यदि गैर-डिफ़ॉल्ट मानों का उपयोग किया जाता है, तो ईवेंट लूप निर्माण (खंड 7.7) के तर्क देखें।
यदि coroutine को इवेंट लूप विधि (आमतौर पर
create_task ) को कॉल करने की आवश्यकता होती है, तो
asyncio.get_event_loop () (तर्कों के बिना) प्रभावी रूप से इसे वापस कर देगा।
२.२ करौटेएक coroutine इस प्रकार बनाया जाता है:
async def foo ( delay_secs ): await asyncio.sleep ( delay_secs ) print ( 'Hello' )
एक coroutine अन्य coroutines को वेट स्टेटमेंट का उपयोग करके लॉन्च करने की अनुमति दे सकता है। एक coroutine में कम से कम एक
प्रतीक्षित कथन होना चाहिए। यह कोराउटाइन को पूरा करने से पहले निष्पादित करने का कारण बनता है, निष्पादन से पहले अगले विवरण तक। एक उदाहरण पर विचार करें:
await asyncio.sleep ( delay_secs ) await asyncio.sleep ( 0 )
पहली पंक्ति में कोड को विलंब समय के लिए रुकने का कारण बनता है, जबकि अन्य कोरटाइन अपने निष्पादन के लिए इस समय का उपयोग करते हैं। 0 की देरी से सभी लंबित कोरटाइन को चक्रीय क्रम में निष्पादित किया जाता है जब तक कि अगली पंक्ति निष्पादित नहीं होती है।
Roundrobin.py का उदाहरण देखें।
2.2.1। एक coroutine की योजना के लिए कतार- EventLoop.create_task तर्क: चलाने के लिए Coroutine। शेड्यूलर जल्द से जल्द शुरू करने के लिए कोरटाइन को कतार में खड़ा करता है। Create_task कॉल तुरंत लौटाता है। तर्क में coroutine आवश्यक तर्कों के साथ फ़ंक्शन कॉल के सिंटैक्स का उपयोग करके निर्दिष्ट किया गया है।
- EventLoop.run_until_complete तर्क: दौड़ने के लिए Coroutine। शेड्यूलर जल्द से जल्द शुरू करने के लिए कोरटाइन को कतार में खड़ा करता है। तर्क में coroutine आवश्यक तर्कों के साथ फ़ंक्शन कॉल के सिंटैक्स का उपयोग करके निर्दिष्ट किया गया है। जब coroutine पूरा हो गया है तो un_until_complete कॉल रिटर्न: यह विधि अनुसूचक से बाहर निकलने का एक तरीका प्रदान करती है।
- प्रतीक्षारत तर्क: एक कॉलआउट चलाने के लिए, फ़ंक्शन कॉल सिंटैक्स का उपयोग करके निर्दिष्ट किया गया। जितनी जल्दी हो सके एक coroutine शुरू करता है। जब तक अपेक्षित कोरआउट में से कोई एक पूरा नहीं हो जाता है, तब तक लंबित कोरआउट अवरुद्ध होता है।
ऊपर
CPython के साथ संगत है। अतिरिक्त
uasyncio विधियों
की चर्चा नोट्स (धारा 2.2.3) में की गई है।
2.2.2 कॉलबैक फ़ंक्शन शुरू करनाकॉलबैक कम समय में निष्पादित करने के लिए डिज़ाइन किए गए
पायथन कार्य होने चाहिए। यह इस तथ्य के कारण है कि पूरे प्रदर्शन के दौरान कोराउटिन काम नहीं कर पाएंगे।
निम्न
EventLoop वर्ग
विधियों कॉलबैक का उपयोग करें:
- call_soon - जितनी जल्दी हो सके कॉल करें। आर्ग्स: कॉलबैक कॉलबैक को चलाने के लिए, * किसी भी स्थिति संबंधी तर्क को कॉमा द्वारा पीछा किया जा सकता है।
- call_later - सेकंड में देरी के बाद कॉल करें। आर्ग्स: देरी, कॉलबैक, * आर्ग्स
- call_later_ms - ms में देरी के बाद कॉल करें। आर्ग्स: देरी, कॉलबैक, * आर्ग्स।
loop = asyncio.get_event_loop () loop.call_soon ( foo , 5 )
२.२.३ नोटएक coroutine में मनमाना रिटर्न मान के साथ
रिटर्न स्टेटमेंट हो सकता है। इस मान को पाने के लिए:
result = await my_coro ()
एक coroutine विधियों द्वारा सीमित किया जा सकता है और इसमें कम से कम एक
प्रतीक्षित कथन होना चाहिए।
२.३ देरीकोरटाइन में देरी के आयोजन के लिए दो विकल्प हैं। देरी के लिए और ऐसे मामलों में जहां अवधि को सटीक होने की आवश्यकता नहीं है, आप उपयोग कर सकते हैं:
async def foo( delay_secs , delay_ms ): await asyncio.sleep ( delay_secs ) print ( 'Hello' ) await asyncio.sleep_ms ( delay_ms )
इस तरह की देरी के दौरान, शेड्यूलर अन्य कोरआउट्स को निष्पादित करेगा। यह समय अनिश्चितता का परिचय दे सकता है, क्योंकि कॉलिंग कॉइन केवल तभी लॉन्च किया जाएगा जब वह वर्तमान में चल रहा है जिसे निष्पादित किया गया है। विलंब की मात्रा आवेदन डेवलपर पर निर्भर करती है, लेकिन यह संभवतः दसियों या सैकड़ों एमएस के आदेश पर होगी; हार्डवेयर डिवाइसेस (अनुभाग 6) के साथ सहभागिता में इस पर आगे चर्चा की गई है।
नींद कार्यों और
नींद_सुबह का उपयोग करके बहुत सटीक देरी की जा सकती है। वे छोटी देरी के लिए सबसे उपयुक्त हैं, क्योंकि शेड्यूलर अन्य कोरआउट को निष्पादित करने में सक्षम नहीं होगा, जबकि विलंब प्रगति पर है।
3.Sinhronizatsiyaअक्सर कोरटाइन के बीच सिंक्रनाइज़ेशन सुनिश्चित करने की आवश्यकता होती है। एक सामान्य उदाहरण तथाकथित "दौड़ की स्थिति" से बचने के लिए है जब एक साथ कई कॉरआउट को एक ही संसाधन तक पहुंच की आवश्यकता होती है। एक उदाहरण
astests.py में प्रदान किया
गया है और
प्रलेखन में चर्चा की गई है। एक और खतरा "मौत को गले लगाना" है, जब प्रत्येक कोरटाइन दूसरे के पूरा होने का इंतजार करता है।
सरल अनुप्रयोगों में, वैश्विक झंडे या संबंधित चर का उपयोग करके सिंक्रनाइज़ेशन प्राप्त किया जा सकता है। एक अधिक सुरुचिपूर्ण दृष्टिकोण सिंक्रनाइज़ेशन कक्षाओं का उपयोग करना है।
Asyn.py मॉड्यूल
इवेंट, बैरियर, सेमाफोर और
कॉन्डिटीयोस वर्गों के "माइक्रो" कार्यान्वयन की पेशकश करता है, जिसका उद्देश्य केवल
एसिंको के साथ उपयोग करना है। वे थ्रेड-ओरिएंटेड नहीं हैं और उन्हें
_thread मॉड्यूल या इंटरप्ट हैंडलर के साथ उपयोग नहीं किया जाना चाहिए, जब तक कि अन्यथा निर्दिष्ट न हो।
लॉक क्लास को भी लागू किया गया है, जो आधिकारिक कार्यान्वयन का एक विकल्प है।
एक और तुल्यकालन समस्या कॉरटीन-उत्पादकों और कोरटाइन-उपभोक्ताओं के साथ उत्पन्न होती है। एक coroutine उत्पादक डेटा उत्पन्न करता है जो एक coroutine उपभोक्ता उपयोग करता है। ऐसा करने के लिए,
asyncio कतार वर्ग प्रदान करता है। कोरटाइन-निर्माता डेटा को कतार में रखता है, जबकि कोरटाइन-उपभोक्ता इसके पूरा होने का इंतजार कर रहा है (समय पर निर्धारित अन्य कार्यों के साथ)।
कतार वर्ग उन वस्तुओं को हटाने के लिए गारंटी प्रदान करता है जिनमें उन्हें प्राप्त किया गया था। वैकल्पिक रूप से, आप
बैरियर वर्ग का उपयोग कर सकते हैं यदि निर्माता कोरआउट को तब तक इंतजार करना चाहिए जब तक कि उपभोक्ता कोरआउट डेटा का उपयोग करने के लिए तैयार न हो।
कक्षाओं का संक्षिप्त विवरण नीचे दिया गया है।
पूर्ण प्रलेखन में अधिक जानकारी।
3.1 तालासाझा संसाधन के लिए
लॉक अद्वितीय पहुँच की गारंटी देता है। निम्न कोड उदाहरण
लॉक क्लास
लॉक का एक उदाहरण बनाता है जो उन सभी ग्राहकों को दिया जाता है जो साझा संसाधन का उपयोग करना चाहते हैं। जब तक यह सफल न हो जाए, तब तक प्रत्येक कॉरटीन लॉक को पकड़ने की कोशिश करता है, जो निष्पादन को रोक देता है:
import uasyncio as asyncio from uasyncio.synchro import Lock async def task(i, lock): while 1: await lock.acquire() print("Acquired lock in task", i) await asyncio.sleep(0.5) lock.release() async def killer(): await asyncio.sleep(10) loop = asyncio.get_event_loop() lock = Lock()
३.१.१.लॉक और टाइमआउटलेखन के समय (5 जनवरी, 2018),
यूसीसियो लॉक वर्ग का विकास आधिकारिक तौर पर पूरा नहीं हुआ है। यदि कोरआउट एक
टाइमआउट (खंड 5.2.2) है , जब ट्रिगर होने पर लॉक की प्रतीक्षा कर रहा है, तो टाइमआउट अप्रभावी होगा। यह
लॉकआउट मिलने तक
TimeoutError प्राप्त नहीं करेगा। एक कार्य को रद्द करने के लिए भी यही बात लागू होती है।
Asyn.py मॉड्यूल
लॉक क्लास प्रदान करता है, जो इन स्थितियों में काम करता है। वर्ग का यह कार्यान्वयन आधिकारिक वर्ग की तुलना में कम कुशल है, लेकिन
सीपीथॉन संस्करण के अनुसार अतिरिक्त इंटरफेस का समर्थन करता है, जिसमें संदर्भ प्रबंधक का उपयोग भी शामिल है।
3.2 घटनाइवेंट एक या कई कॉरआउट्स को थामने का अवसर पैदा करता है, जबकि दूसरा उनके जारी रहने के बारे में संकेत देता है।
इवेंट का एक उदाहरण सभी कॉरआउट्स के लिए उपलब्ध है जो इसका उपयोग करते हैं:
import asyn event = asyn.Event ()
एक
कोरआउट एक
प्रतीक्षा की घोषणा करके एक
घटना की प्रतीक्षा करता है , जिसके बाद निष्पादन तब तक रुकता है जब तक कि अन्य coroutines
घटना की घोषणा नहीं कर
देते ।
() ।
पूरी जानकारी ।
एक समस्या उत्पन्न हो सकती है यदि
इवेंट.सेट () लूपिंग निर्माण में जारी किया जाता है; कोड को तब तक इंतजार करना चाहिए जब तक कि सभी लंबित वस्तुओं को फिर से स्थापित करने से पहले घटना तक पहुंच न हो। मामले में जब कोई
कोरो किसी घटना की उम्मीद करता है, तो यह एक
कोरो घटना को प्राप्त करने के द्वारा प्राप्त किया जा सकता है:
async def eventwait ( event ): await event event.clear()
ईवेंट ट्रिगर करने वाले कोरआउट की जाँच करता है कि यह सेवित किया गया है:
async def foo ( event ): while True :
मामले में जब कई
कोर एक घटना के सिंक्रनाइज़ेशन की प्रतीक्षा कर रहे हैं, तो पुष्टिकरण घटना का उपयोग करके समस्या को हल किया जा सकता है। प्रत्येक
कोरो को एक अलग घटना की आवश्यकता होती है।
async def eventwait ( , ack_event ): await event ack_event.set ()
इसका एक उदाहरण
asyntest.py में
event_test फ़ंक्शन में
दिया गया है । यह बोझिल है ज्यादातर मामलों में - यहां तक कि एक प्रतीक्षा
कोरो के साथ -
बैरियर वर्ग, नीचे प्रस्तुत किया गया है, एक सरल दृष्टिकोण प्रदान करता है।
एक घटना भी बाधा हैंडलर और
कोरो के बीच संचार का साधन प्रदान कर सकती है। हैंडलर हार्डवेयर को बनाए रखता है और ईवेंट सेट करता है, जो पहले से ही सामान्य मोड में
कोरो द्वारा जांचा जाता है।
3.2.1 घटना मानईवेंट .सेट () विधि किसी भी प्रकार का वैकल्पिक डेटा मान ले सकती है।
कोरो , एक घटना की प्रतीक्षा कर रहा है, इसे
event.value () के साथ प्राप्त कर सकता है। ध्यान दें कि
event.clear () कोई भी सेट
नहीं किया जाएगा । घटना को सेट करने के लिए इस का एक सामान्य उपयोग ईवेंट को जारी करने के लिए है।
(utime.ticks_ms ()) । किसी भी घटना के लिए प्रतीक्षा करने वाला कोई
कोरो विलंब का निर्धारण कर सकता है, उदाहरण के लिए, इसके लिए क्षतिपूर्ति करना।
३.३ बाधाबैरियर वर्ग के लिए दो उपयोग हैं।
सबसे पहले, यह एक coroutine को निलंबित कर सकता है जब तक कि एक या कई अन्य coroutines पूर्ण नहीं हो जाते।
दूसरे, यह एक निश्चित बिंदु पर कई कोरटाइन को पूरा करने की अनुमति देता है। उदाहरण के लिए, एक निर्माता और एक उपभोक्ता उस बिंदु पर सिंक्रनाइज़ कर सकते हैं जहां निर्माता के पास डेटा है, और उपभोक्ता इसका उपयोग करने के लिए तैयार है। निष्पादन के समय,
बैरियर को हटाने से पहले
बैरियर अतिरिक्त कॉलबैक जारी कर सकता है और सभी लंबित घटनाएं जारी रह सकती हैं।
कॉलबैक एक फ़ंक्शन या कोरटाइन हो सकता है। अधिकांश अनुप्रयोगों में, फ़ंक्शन का सबसे अधिक उपयोग किया जाएगा: यह बाधा हटाने से पहले निष्पादित होने की गारंटी दी जा सकती है।
एक उदाहरण
asyntest.py में
बाधा_ test फ़ंक्शन है। इस कार्यक्रम के कोड स्निपेट में:
import asyn def callback(text): print(text) barrier = asyn.Barrier(3, callback, ('Synch',)) async def report(): for i in range(5): print('{} '.format(i), end='') await barrier
रिपोर्ट के कई उदाहरण coroutine अपना परिणाम प्रिंट करते हैं और तब तक रोकते हैं जब तक कि अन्य उदाहरण भी पूरे नहीं हो जाते हैं और
बाधा जारी रहने का इंतजार करते हैं। इस बिंदु पर, एक कॉलबैक बनाया जा रहा है। पूरा होने पर, मूल कोरटाइन फिर से शुरू होता है।
३.४ सेमाफोरसेमाफोर कोरआउट की संख्या को सीमित करता है जो संसाधन तक पहुंच सकता है। इसका उपयोग किसी विशेष कोरआउट के उदाहरणों की संख्या को सीमित करने के लिए किया जा सकता है जो एक साथ चल सकते हैं। यह एक एक्सेस काउंटर का उपयोग करके किया जाता है, जो कि कंस्ट्रक्टर द्वारा आरंभीकृत किया जाता है और हर बार कोरटाइन को एक सेमीफोर प्राप्त होता है।
संदर्भ प्रबंधक में इसका उपयोग करने का सबसे आसान तरीका:
import asyn sema = asyn.Semaphore(3) async def foo(sema): async with sema:
एक उदाहरण
asyntest.py में
semaphore_test फ़ंक्शन है।
3.4.1 ( सीमित ) सेमाफोरयह
सेमाफोर वर्ग के समान ही काम करता है, सिवाय इसके कि यदि
रिलीज़ विधि एक्सेस काउंटर को इसके प्रारंभिक मान से अधिक का कारण बनाती है, तो एक
ValueError सेट है।
3.5 कतारक्यू क्लास को आधिकारिक
uasycio द्वारा बनाए रखा जाता है और
aqtest.py नमूना कार्यक्रम इसके उपयोग को प्रदर्शित करता है। कतार इस प्रकार बनाई गई है:
from uasyncio.queues import Queue q = Queue ()
एक विशिष्ट निर्माता कोरटाइन निम्नानुसार काम कर सकता है:
async def producer(q): while True: result = await slow_process()
और उपभोक्ता coroutine निम्नानुसार काम कर सकता है:
async def consumer(q): while True: result = await(q.get())
कतार वर्ग महत्वपूर्ण अतिरिक्त कार्यक्षमता प्रदान करता है जब कतारों का आकार सीमित हो सकता है और स्थिति को प्रदूषित किया जा सकता है। एक खाली कतार के साथ व्यवहार (यदि आकार सीमित है) और एक पूर्ण कतार के साथ व्यवहार को नियंत्रित किया जा सकता है।
इस बारे में प्रलेखन कोड में है।3.6 अन्य वर्गों सिंकलाइब्रेरी asyn.py प्रदान करता है "माइक्रो" कार्यान्वयन जिसमें कुछ सुविधाएं CPython । हालतवर्ग एक coroutine को एक बंद संसाधन पर प्रतीक्षा कर रहे अन्य coroutines को सूचित करने की अनुमति देता है। अधिसूचना प्राप्त करने के बाद, वे संसाधन तक पहुंच प्राप्त करेंगे और बदले में अनलॉक करेंगे। एक सूचना कोरआउट को अधिसूचित किए जाने वाले कोरआउट की संख्या को सीमित कर सकता है। Gather वर्ग आपको coroutines की एक सूची चलाने की अनुमति देता है। उत्तरार्द्ध के पूरा होने पर, परिणामों की एक सूची वापस आ जाएगी। यह "माइक्रो" कार्यान्वयन एक अलग वाक्यविन्यास का उपयोग करता है। टाइमआउट किसी भी कोरआउट के लिए लागू किया जा सकता है।4 asyncio के लिए कक्षाएं विकसित करनाविकासशील डिवाइस चालकों के संदर्भ में, लक्ष्य यह सुनिश्चित करना है कि वे गैर-अवरुद्ध काम करते हैं। एक coroutine ड्राइवर को यह सुनिश्चित करना चाहिए कि अन्य coroutines निष्पादित हैं जबकि ड्राइवर हार्डवेयर संचालन करने के लिए डिवाइस की प्रतीक्षा कर रहा है। उदाहरण के लिए, UART में आने वाले डेटा या बटन दबाने वाले उपयोगकर्ता के लिए प्रतीक्षा करने वाला कार्य अन्य ईवेंट को तब तक शेड्यूल करने की अनुमति देता है जब तक कि ईवेंट न हो जाए।उम्मीदों के साथ 4.1 वर्ग का इंतजारcoroutine निष्पादन को निलंबित कर सकते हैं, वस्तु के लिए इंतज़ार कर awaitable । CPython के तहत , एक कस्टम प्रतीक्षा योग्य वर्ग विशेष __await__ पद्धति को लागू करके बनाया गया हैजेनरेटर वापस आ जाता है। निम्न श्रेणी का उपयोग किया जाता है: import uasyncio as asyncio class Foo(): def __await__(self): for n in range(5): print('__await__ called') yield from asyncio.sleep(1)
वर्तमान में MicroPython का समर्थन नहीं __await__ ( मुद्दा # 2678 ) और समाधान के लिए प्रयोग की जाने वाली __iter__ । स्ट्रिंग __iter__ = __await__ CPython और MicroPython के बीच पोर्टेबिलिटी प्रदान करता है । कोड उदाहरण, वर्गों को देखने के इवेंट, बैरियर, रद्द करने योग्य, स्थिति में asyn.py ।4.1.1 संदर्भ प्रबंधकों में उपयोगअपेक्षित वस्तुओं को समकालिक या अतुल्यकालिक संदर्भ प्रबंधकों में उपयोग किया जा सकता है, जो आवश्यक विशेष तरीके प्रदान करते हैं। वाक्य रचना: with await awaitable as a:
इसे प्राप्त करने के लिए, __await__ जनरेटर को स्व वापस करना होगा । इसे किसी भी वैरिएबल को क्लॉज में पास किया जाता है, और विशेष तरीकों को काम करने की भी अनुमति देता है। Asyn.Condition और asyntest.condition_test देखें, जहां हालत वर्ग प्रतीक्षा का उपयोग करता है और एक तुल्यकालिक संदर्भ प्रबंधक में उपयोग किया जा सकता है।में 4.1.2 का इंतजार coroutineभाषा अजगर की आवश्यकता है __await__ जनरेटर समारोह था। में MicroPython जनरेटर और coroutines, समान हैं तो समाधान का उपयोग करने के लिए है Coro से उपज बयान (args) ।इस गाइड का उद्देश्य कोड की पेशकश करना है जो कि सीपीथॉन 3.5 या बाद में पोर्टेबल है । में CPython जनरेटर और coroutines अर्थ में अलग हैं। में CPython coroutine है __await__ विशेष विधि है, जो जनरेटर निकालता है। यह पोर्टेबल है: up = False
ध्यान दें कि __await__, asyncio.sleep (1) से उपज CPython द्वारा अनुमत है । मुझे अभी तक समझ नहीं आया कि यह कैसे हासिल किया जाता है।4.2 अतुल्यकालिक पुनरावृत्तअतुल्यकालिक पुनरावृत्तियाँ एक सीमित या अनंत मानों को वापस करने का साधन प्रदान करते हैं और जब वे केवल-पढ़ने के उपकरण से आते हैं, तो अनुक्रमिक डेटा तत्वों को प्राप्त करने के साधन के रूप में उपयोग किया जा सकता है। एक एसिंक्रोनस पुनरावर्तक अपने अगले तरीके में एसिंक्रोनस कोड को कॉल करता है । वर्ग को निम्नलिखित आवश्यकताओं को पूरा करना चाहिए:- उन्होंने कहा कि एक विधि है __aiter__ , में परिभाषित async डीईएफ़ और एक अतुल्यकालिक iterator देता है।
- इसकी एक विधि __anext__ है , जो कि स्वयं एक coroutine है - अर्थात, async def के माध्यम से परिभाषित किया गया है और जिसमें कम से कम एक प्रतीक्षित कथन है । पुनरावृति को रोकने के लिए, इसे StopAsyncIteration अपवाद उठाना होगा ।
नीचे दिखाए गए अनुसार async का उपयोग करके सीरियल वैल्यू को पुनः प्राप्त किया गया है: class AsyncIterable: def __init__(self): self.data = (1, 2, 3, 4, 5) self.index = 0 async def __aiter__(self): return self async def __anext__(self): data = await self.fetch_data() if data: return data else: raise StopAsyncIteration async def fetch_data(self): await asyncio.sleep(0.1)
4.3 अतुल्यकालिक संदर्भ प्रबंधककक्षाएं सह-कार्यक्रम के प्रवेश और निकास प्रक्रियाओं वाले अतुल्यकालिक संदर्भ प्रबंधकों का समर्थन करने के लिए डिज़ाइन की जा सकती हैं। एक उदाहरण ऊपर वर्णित लॉक क्लास है। इसमें __aenter__ coroutine है , जिसे तार्किक रूप से अतुल्यकालिक ऑपरेशन के लिए आवश्यक है। संदर्भ प्रबंधक के अतुल्यकालिक प्रोटोकॉल का समर्थन करने के लिए, इसकी __aexit__ विधि भी एक coroutine होनी चाहिए, जो कि asyncio.sleep (0) को शामिल करके हासिल की गई है । इस तरह की कक्षाएं निम्नलिखित सिंटैक्स के साथ एक कोरआउट से सुलभ हैं: async def bar ( lock ): async with lock: print ( « bar » )
नियमित संदर्भ प्रबंधकों के साथ के रूप में, बाहर निकलने की विधि को गारंटी दी जाती है जब संदर्भ प्रबंधक अपना काम पूरा करता है, हमेशा की तरह, और एक अपवाद के माध्यम से। इस लक्ष्य को हासिल करने के लिए हमें विशेष तकनीक का उपयोग __aenter__ और __aexit__ , coroutines रूप में पहचाना जा करने के लिए एक और coroutine या का इंतजार कर awaitable वस्तु। यह उदाहरण लॉक क्लास से लिया गया है : async def __aenter__(self): await self.acquire()
यदि async के साथ चर खंड के रूप में होता है , तो चर को __aenter__ द्वारा लौटाया गया मान मिलता है ।सही व्यवहार सुनिश्चित करने के लिए, फर्मवेयर V1.9.10 या बाद का होना चाहिए।5. टाइमआउट के अपवाद और कार्यों को रद्द करने के कारणये विषय संबंधित हैं: uasyncio में कार्यों को रद्द करना और किसी कार्य के लिए टाइमआउट लागू करना, विशेष तरीके से कार्य के अपवाद को फेंकना शामिल है।5.1 अपवादयदि एक कोरटाइन में एक एक्साईशन होता है, तो इसे इस कोरआउट में या इसके पूरा होने की प्रतीक्षा में एक कोरआउट में संसाधित किया जाना चाहिए। यह सुनिश्चित करता है कि अपवाद शेड्यूलर पर लागू नहीं होता है। यदि कोई अपवाद होता है, तो शेड्यूलर उस कोड के अपवाद को पास करके काम करना बंद कर देगा जो शेड्यूलर ने प्रारंभ किया था। इसलिए, अनुसूचक को रोकने से बचने के लिए, coroutine को loop.create_task () के साथ लॉन्च किया गया है, जिसे किसी भी अपवाद को पकड़ना चाहिए। एक coroutine में एक अपवाद को फेंकने के लिए फेंक या बंदका उपयोग करना अनुचित है। यह यूसिंसीओ को नष्ट कर देता है , जिससे कोरटाइन शुरू हो जाता है और संभवतः बाहर निकल जाता है जब यह अभी भी निष्पादन कतार में है।उपरोक्त उदाहरण इस स्थिति को दर्शाता है। अगर अंत तक काम करने दिया जाए तो यह उम्मीद के मुताबिक काम करता है। import uasyncio as asyncio async def foo(): await asyncio.sleep(3) print('About to throw exception.') 1/0 async def bar(): try: await foo() except ZeroDivisionError: print('foo - 0')
हालांकि, एक कीबोर्ड इंटरप्ट जारी करने से अपवाद घटना पाश में जाता है। ऐसा इसलिए है क्योंकि uasyncio.sleep का निष्पादन इवेंट लूप को दिया जाता है। इसलिए, जिन अनुप्रयोगों को कीबोर्ड व्यवधान के जवाब में एक स्पष्ट कोड की आवश्यकता होती है, उन्हें इवेंट लूप स्तर पर अपवाद को पकड़ना चाहिए।5.2 रद्द करें और समयबाह्यजैसा कि ऊपर उल्लेख किया गया है, ये फ़ंक्शन विशेष माइक्रोपायथॉन विधि coroutine pend_throw का उपयोग करके एक विशेष तरीके से कार्य के लिए अपवाद बढ़ाकर काम करते हैं । यह कैसे काम करता है यह संस्करण पर निर्भर करता है। आधिकारिक uasyncio v.2.0 में, एक अपवाद को अगले निर्धारित कार्य तक संसाधित नहीं किया जाता है। यदि कार्य नींद की उम्मीद करता है, तो यह देरी करता हैइनपुट-आउटपुट। समयावधि उनके नाममात्र अवधि से आगे बढ़ सकती है। अन्य कार्यों का पूर्ववत कार्य निर्धारित नहीं किया जा सकता है जब पूर्ववत किया गया है।वर्तमान में एक वर्कअराउंड और दो समाधान हैं।- वर्कअराउंड : एसाइन लाइब्रेरी कार्यों या कार्य समूहों को रद्द करने के लिए प्रतीक्षा करने का साधन प्रदान करता है। एक नौकरी रद्द करें (खंड 5.2.1) देखें।
- पॉल सोकोलोव्स्की पुस्तकालय uasyncio v2.4 प्रदान करता है , लेकिन इसके लिए इसकी Pycopy फर्मवेयर की आवश्यकता होती है ।
- Fast_io लाइब्रेरी uasyncio पायथन में इस समस्या को हल करती है(कम सुरुचिपूर्ण तरीके से) और आधिकारिक फर्मवेयर पर चलती है।
यहाँ उपयोग किए गए अपवादों का पदानुक्रम अपवाद-रद्द-निष्पादित-समय-समय पर है ।5.2.1 एक नौकरी रद्द करनाuasyncio एक रद्द (कोरो) फ़ंक्शन प्रदान करता है । यह pend_throw coroutine का उपयोग करने के लिए अपवाद फेंककर काम करता है । यह नेस्टेड कोरटाइन के साथ भी काम करता है। उपयोग निम्नानुसार है: async def foo(): while True:
यदि यह उदाहरण uasyncio v2.0 के तहत चलाया जाता है , तो जब बार के मुद्दे रद्द हो जाते हैं तो यह अगले अनुसूचित फू तक प्रभावी नहीं होगा , और जब फू रद्द किया जाता है तो 10 सेकंड तक की देरी हो सकती है । देरी का एक अन्य स्रोत तब होगा जब फू I / O की प्रतीक्षा कर रहा है। जहां भी विलंब होता है, बार निर्धारित नहीं कर पाएगा कि क्या फू रद्द कर दिया गया है। यह कुछ उपयोग मामलों में मायने रखता है। पॉल सोकोलोव्स्की या fast_io पुस्तकालयोंका उपयोग करते समय , यह नींद का उपयोग करने के लिए पर्याप्त है (0): async def foo(): while True:
यह uasyncio v2.0 में भी काम करेगा अगर फू (और किसी भी लंबित कोरटाइन फू ) कभी नींद नहीं लौटी और I / O का इंतजार नहीं किया।व्यवहार जो कि लापरवाह हो सकता है, तब होता है जब एक coroutine जो create_task द्वारा चलाया जाता है और स्टैंडबाय मोड में होता है, उसे रद्द करने की उम्मीद की जाती है । इस स्निपेट पर विचार करें: async def foo(): while True:
जब फू रद्द कर दिया जाता है, तो इसे अनुसूचक कतार से हटा दिया जाता है; क्योंकि इसमें रिटर्न स्टेटमेंट का अभाव है , इसलिए कॉलिंग प्रक्रिया foo_runner कभी भी शुरू नहीं होती है। यह अनुशंसा की जाती है कि आप हमेशा पूर्ववत होने के लिए फ़ंक्शन के सबसे बाहरी दायरे में अपवाद को पकड़ें: async def foo(): try: while True: await asyncio.sleep(10) await my_coro except asyncio.CancelledError: return
इस मामले में, my_coro को अपवाद को पकड़ने की आवश्यकता नहीं है, क्योंकि यह कॉलिंग चैनल को प्रचारित किया जाएगा और वहां कब्जा कर लिया जाएगा।नोट।
जब कोर्युटिन को अनुसूचक के बाहर उपयोग किया जाता है, तो कॉउटआउट के करीबी या फेंकने के तरीकों का उपयोग करने से मना किया जाता है। यह शेड्यूलर को कमज़ोर करता है, जिससे कोरटाइन को कोड निष्पादित करने के लिए मजबूर किया जाता है, भले ही वह अनुसूचित न हो। इसके अवांछनीय परिणाम हो सकते हैं।5.2.2समयबाह्य के साथ कोआउटआउट uasyncio विधियों का उपयोग करके कार्यान्वित किया जाता है .wait_for () और .wait_for_ms () । वे तर्क के रूप में, क्रमशः सेकंड या एमएस में कोरटाइन और विलंबता लेते हैं। यदि समय समाप्ति की समय सीमा समाप्त हो जाती है, तो एक टाइमआउट Error को pend_throw का उपयोग करके कॉरआउट में फेंक दिया जाएगा। यह अपवाद उपयोगकर्ता द्वारा या कॉलर द्वारा पकड़ा जाना चाहिए। यह ऊपर वर्णित कारण के लिए आवश्यक है: यदि समय समाप्त हो जाता है, तो इसे रद्द कर दिया जाता है। जब तक त्रुटि को पकड़ा और वापस नहीं किया जाता है, तब तक कॉलर को जारी रखने का एकमात्र तरीका अपवाद को पकड़ना है।जहां अपवाद को कोरटाइन द्वारा पकड़ा गया था, मुझे स्पष्ट विफलता नहीं थी अगर बाहरी दायरे में अपवाद को नहीं पकड़ा गया था, जैसा कि नीचे दिखाया गया है: import uasyncio as asyncio async def forever(): try: print('Starting') while True: await asyncio.sleep_ms(300) print('Got here') except asyncio.TimeoutError: print('Got timeout')
वैकल्पिक रूप से, आप कॉलिंग फ़ंक्शन को इंटरसेप्ट कर सकते हैं: import uasyncio as asyncio async def forever(): print('Starting') while True: await asyncio.sleep_ms(300) print('Got here') async def foo(): try: await asyncio.wait_for(forever(), 5) except asyncio.TimeoutError: pass print('Timeout elapsed.') await asyncio.sleep(2) loop = asyncio.get_event_loop() loop.run_until_complete(foo())
Uasyncio v2.0 के लिए ध्यान दें ।यह पॉल सोकोलोव्स्की या fast_io पुस्तकालयों पर लागू नहीं होता है ।यदि कोरटाइन लंबे समय तक देरी के साथ asyncio.sleep (t) का इंतजार करना शुरू कर देता है, तो coroutine तब तक पुनरारंभ नहीं होगा जब तक कि टी समाप्त नहीं हो जाता । यदि नींद समाप्त होने से पहले समय समाप्त हो गया है , तो एक समय समाप्त हो जाएगा, जब कोरआउट पुनः लोड किया जाएगा - अर्थात जब टी समाप्त हो रहा है । वास्तविक समय में और कॉल करने वाले के दृष्टिकोण से, उसके टाइमआउट की प्रतिक्रिया में देरी होगी।यदि यह आवेदन के लिए महत्वपूर्ण है, तो लूप में कम समय की प्रतीक्षा करते हुए एक लंबी देरी बनाएं। coroutineasyn.sleep इसका समर्थन करता है।6 उपकरणों के साथसहभागिता uasyncio और बाहरी अतुल्यकालिक घटनाओं के बीच बातचीत का आधार मतदान है। त्वरित प्रतिक्रिया की आवश्यकता वाले हार्डवेयर एक रुकावट का उपयोग कर सकते हैं। लेकिन इंटरप्ट रुटीन (ISR) और यूजर कोरआउट के बीच की बातचीत चुनाव पर आधारित होगी। उदाहरण के लिए, एक ISR ईवेंट को कॉल कर सकता है या एक वैश्विक ध्वज सेट कर सकता है , जबकि एक परिणाम प्राप्त होने का इंतजार कर रहा एक कोर हर बार एक अनुरोध निर्धारित होता है।पूछताछ दो तरीकों से की जा सकती है, स्पष्ट या निहित। उत्तरार्द्ध धारा I / O का उपयोग करके किया जाता हैएक तंत्र, जो UART और सॉकेट जैसे स्ट्रीमिंग उपकरणों के लिए डिज़ाइन किया गया सिस्टम है । सरलतम स्पष्ट सर्वेक्षण में, निम्नलिखित कोड शामिल हो सकते हैं: async def poll_my_device(): global my_flag
इसके बजाय, एक उदाहरण चर के लिए वैश्विक ध्वज, तो आप उपयोग कर सकते हैं घटना या का उपयोग करने का एक उदाहरण इंतजार । एक स्पष्ट सर्वेक्षण नीचे चर्चा की गई है।निहित मतदान में एक चालक को विकसित करना शामिल है जो स्ट्रीमिंग I / O डिवाइस के रूप में कार्य करेगा, जैसे UART या स्ट्रीम I / O सॉकेट , जो select.poll पायथन सिस्टम का उपयोग करके उपकरणों को मतदान करता है: चूंकि C में मतदान किया जाता है, यह तेजी से और अधिक कुशल है। स्पष्ट मतदान। धारा I / O के उपयोग की चर्चा खंड 6.3 में की गई है। इसकी प्रभावशीलता के कारण, निहित मतदान सबसे तेज़ I / O डिवाइस ड्राइवरों को एक फायदा देता है: स्ट्रीमिंग ड्राइवरों को कई उपकरणों के लिए बनाया जा सकता है जिन्हें आमतौर पर स्ट्रीमिंग डिवाइस के रूप में नहीं माना जाता है। इस पर खंड 6.4 में अधिक विस्तार से चर्चा की गई है।6.1 सिंक मुद्देदोनों स्पष्ट और निहित चुनाव वर्तमान में चक्रीय योजना पर आधारित हैं। मान लीजिए कि I / O एक साथ एन कस्टम कोरआउट्स के साथ काम करता है, जिनमें से प्रत्येक शून्य विलंब से चलता है। जब I / O परोसा जाता है, तो सभी उपयोगकर्ता संचालन निर्धारित होते ही इसे फिर से मतदान किया जाएगा। डिजाइन करते समय अनुमानित देरी पर विचार किया जाना चाहिए। मुझे / ओ चैनलों को बफ़रिंग की आवश्यकता होती है, आईएसआर सर्विसिंग उपकरण के साथ वास्तविक समय में बफ़र और कोरटाइन से, भराव समय पर बफ़र भरने या मुक्त करने की आवश्यकता होती है।परे जाने की संभावना पर विचार करना भी आवश्यक है: यह वह स्थिति है जब कोरटाइन द्वारा पूछताछ की जाने वाली चीज को कोरटाइन द्वारा वास्तव में योजनाबद्ध करने से पहले एक से अधिक बार होता है।एक और समय मुद्दा विलंबता सटीकता है। अगर कोरटाइन जारी करता है await asyncio.sleep_ms ( t )
शेड्यूलर गारंटी देता है कि निष्पादन कम से कम t ms के लिए निलंबित कर दिया जाएगा। वास्तविक विलंब टी से अधिक हो सकता है, जो वर्तमान सिस्टम लोड पर निर्भर करता है। यदि इस समय अन्य कोराउटीन गैर-शून्य देरी के पूरा होने की प्रतीक्षा कर रहे हैं, तो अगली पंक्ति को तुरंत निष्पादन के लिए निर्धारित किया जाएगा। लेकिन अगर अन्य कोरटाइन को भी निष्पादन का इंतजार है (या तो क्योंकि उन्होंने शून्य देरी से उत्सर्जन किया, या क्योंकि उनका समय भी समाप्त हो गया है), वे पहले निष्पादित करने के लिए निर्धारित हो सकते हैं। यह नींद () और sleep_ms () कार्यों में सिंक्रनाइज़ेशन अनिश्चितता का परिचय देता है । इस अतिप्रवाह के लिए सबसे खराब स्थिति मूल्य की गणना इस तरह के सभी कोराउटीन के रनटाइम मूल्यों को समापक द्वारा सबसे खराब स्थिति संचरण समय निर्धारित करने के लिए की जा सकती है।Fast_io संस्करण uasyncio में इस संदर्भ एक तरीका प्रदान करता सुनिश्चित करना है कि धारा आई / ओ अनुसूचक से प्रत्येक यात्रा पर परामर्श किया जाएगा। यह उम्मीद है कि आधिकारिक uasyncio नियत समय में प्रासंगिक संशोधनों को स्वीकार करेंगे।6.2 कोरटाइन्स का उपयोग करने वाले उपकरणों से पूछताछ करनायह एक सरल तरीका है जो उन उपकरणों के लिए सबसे उपयुक्त है जिन्हें अपेक्षाकृत कम गति से पूछताछ की जा सकती है। यह मुख्य रूप से इस तथ्य के कारण है कि एक छोटे (या शून्य) मतदान अंतराल के साथ मतदान इस तथ्य को जन्म दे सकता है कि कोरटाउन अंतराल में गिरने के लिए अधिक प्रोसेसर समय की तुलना में अधिक वांछनीय है। Apoll.pyउदाहरण Pyboard एक्सेलेरोमीटर को क्वेरी करके इस दृष्टिकोण को प्रदर्शित करता है100 एमएस के अंतराल के साथ। यह शोर को अनदेखा करने के लिए सरल फ़िल्टरिंग करता है, और हर दो सेकंड में एक संदेश प्रिंट करता है यदि कोई आंदोलन नहीं होता है। Aswitch.pyउदाहरण स्विच और बटन उपकरणों के लिए ड्राइवर प्रदान करता है। पढ़ने और लिखने में सक्षम डिवाइस के लिए एक उदाहरण ड्राइवर नीचे दिखाया गया है। परीक्षण में आसानी के लिए, Pyboard UART 4 एक सशर्त डिवाइस का अनुकरण करता है। ड्राइवर को लागू करता है RecordOrientedUart वर्गजिसमें बाइट उदाहरणों से मिलकर चर-लंबाई के रिकॉर्ड में डेटा की आपूर्ति की जाती है। ऑब्जेक्ट भेजने से पहले एक सीमांकक जोड़ता है और आने वाले डेटा को बफ़र करता है जब तक कि एक जोड़ा सीमांकक प्राप्त नहीं होता है। स्ट्रीमिंग इनपुट / आउटपुट की तुलना में UART का उपयोग करने के लिए यह सिर्फ एक डेमो और एक अक्षम तरीका है।अतुल्यकालिक हस्तांतरण को प्रदर्शित करने के लिए, हम मानते हैं कि उत्सर्जित डिवाइस के सत्यापन का एक साधन है कि हस्तांतरण पूरा हो गया है और आवेदन को हमें इंतजार करना होगा। इस उदाहरण में कोई भी धारणा सही नहीं है, लेकिन कोड asyncio.sleep (0.1) की प्रतीक्षा करके इसे नकली करता है ।शुरू करने के लिए, Pyboard X1 और X2 (UART Txd और Rxd) के आउटपुट कनेक्ट करना न भूलें import uasyncio as asyncio from pyb import UART class RecordOrientedUart(): DELIMITER = b'\0' def __init__(self): self.uart = UART(4, 9600) self.data = b'' def __iter__(self):
6.3 स्ट्रीमिंग तंत्र ( स्ट्रीम ) का उपयोग करते हुएउदाहरण Pyboard माइक्रोप्रोसेसर के एक UART पर एक साथ इनपुट-आउटपुट प्रदर्शित करता है ।शुरू करने के लिए, Pyboard X1 और X2 (UART Txd और Rxd) के आउटपुट कनेक्ट करें import uasyncio as asyncio from pyb import UART uart = UART(4, 9600) async def sender(): swriter = asyncio.StreamWriter(uart, {}) while True: await swriter.awrite('Hello uart\n') await asyncio.sleep(2) async def receiver(): sreader = asyncio.StreamReader(uart) while True: res = await sreader.readline() print('Received', res) loop = asyncio.get_event_loop() loop.create_task(sender()) loop.create_task(receiver()) loop.run_forever()
Uasyncio लाइब्रेरी में __init__.py को सपोर्टिंग कोड मिल सकता है । तंत्र काम करता है क्योंकि डिवाइस ड्राइवर ( C में लिखा गया ) निम्नलिखित विधियों को लागू करता है: ioctl, read, readline और write । धारा 6.4: एक स्ट्रीमिंग डिवाइस ड्राइवर लिखने से यह पता चलता है कि ऐसे ड्राइवर पायथन में कैसे लिखे जा सकते हैं ।UART किसी भी समय डेटा प्राप्त कर सकता है। जब भी शेड्यूलर लाभ नियंत्रित करता है, तो आने वाले लंबित वर्णों के लिए स्ट्रीमिंग I / O तंत्र जाँच करता है। जब कोराउटिन चल रहा होता है, तो बाधित दिनचर्या बफ़र आने वाले पात्रों; जब कोराउट अनुसूचक को रास्ता देता है तो उन्हें हटा दिया जाएगा। इसलिए, UART अनुप्रयोगों को डिज़ाइन किया जाना चाहिए ताकि कॉउटर बफर शेड्यूल और डेटा हानि से बचने के लिए अनुसूचक को स्थानांतरण के बीच के समय को कम कर दें। यह एक बड़े UART रीड बफर, या कम डेटा दर का उपयोग करके सुधार किया जा सकता है। वैकल्पिक रूप से, हार्डवेयर प्रवाह नियंत्रण एक समाधान प्रदान करेगा यदि डेटा स्रोत इसका समर्थन करता है।6.3.1 UART के ड्राइवर का उदाहरणकार्यक्रम auart_hd.pyएक आधा-द्वैध डिवाइस के साथ संचार विधि दिखाता है, जैसे कि एटी मॉडेम कमांड सेट पर प्रतिक्रिया देने वाला उपकरण। हाफ डुप्लेक्स का अर्थ है कि डिवाइस कभी भी अवांछित डेटा नहीं भेजता है: इसके स्थानांतरण हमेशा मास्टर से प्राप्त आदेश के जवाब में किए जाते हैं। दो वायर्ड कनेक्शनों के साथ पाइबोर्डपर एक परीक्षण चलाकर डिवाइस का अनुकरण किया जाता है । (बहुत ही सरलीकृत) उत्सर्जित डिवाइस धीमी कमांड को अनुकरण करने के लिए प्रत्येक के बीच ठहराव के साथ डेटा की चार लाइनें भेजकर किसी भी आदेश का जवाब देता है।विज़ार्ड एक कमांड भेजता है, लेकिन पहले से पता नहीं है कि डेटा की कितनी पंक्तियों को वापस किया जाएगा। यह एक पुनरारंभ टाइमर शुरू करता है जो हर बार एक पंक्ति प्राप्त होने पर पुनरारंभ होता है। जब टाइमर समाप्त हो जाता है, तो यह माना जाता है कि डिवाइस ने ट्रांसमिशन पूरा कर लिया है और प्राप्त लाइनों की एक सूची वापस आ गई है।एक उपकरण विफलता का मामला भी प्रदर्शित किया जाता है, जो प्रतिक्रिया की प्रतीक्षा करने से पहले ट्रांसमिशन को स्किप करके हासिल किया जाता है। समय समाप्त होने के बाद, एक खाली सूची वापस आ जाती है। अधिक विवरण के लिए कोड टिप्पणियां देखें।स्ट्रीमिंग के 6.4 विकास (ड्राइवरों स्ट्रीम ) इकाईधारा इनपुट / आउटपुट तंत्र ( आई / ओ स्ट्रीम स्ट्रीमिंग के संचालन को नियंत्रित करने के लिए) मैं / इस तरह के UART और सॉकेट के रूप में हे उपकरणों ( सॉकेट)। तंत्र किसी भी नियमित रूप से मतदान डिवाइस के ड्राइवरों द्वारा कतार में किसी भी डिवाइस की तत्परता को मतदान का चयन करते हुए शेड्यूलर को सौंपकर उपयोग किया जा सकता है । यह कई coroutine संचालन करने से अधिक कुशल है, जिनमें से प्रत्येक डिवाइस को पोल करता है, आंशिक रूप से क्योंकि चयन C में लिखा गया है , और यह भी क्योंकि मतदान करने वाले कोरआउट को विलंबित स्थिति तक पहुंचने में देरी होती है।स्ट्रीमिंग इनपुट / आउटपुट तंत्र को सर्विस करने में सक्षम एक डिवाइस ड्राइवर को बेहतर तरीके से स्ट्रीमराइडर, स्ट्रीमविटर का समर्थन करना चाहिए। एक पठनीय डिवाइस को कम से कम एक विधि प्रदान करनी चाहिए। कृपया ध्यान दें कि ये समकालिक तरीके हैं। Ioctl विधि (नीचे देखें) यह सुनिश्चित करती है कि उन्हें केवल डेटा उपलब्ध होने पर कहा जाता है। जितना संभव हो उतना डेटा का उपयोग करके तरीकों को जितनी जल्दी हो सके वापस किया जाना चाहिए।readline () जितना संभव हो उतने वर्ण लौटाएं, किसी भी newline वर्ण तक। यदि आवश्यक हो तो StreamReader.readline ()पढ़े (n) अधिक से अधिक वर्ण लौटाएं, लेकिन n से अधिक नहीं । यदि आवश्यक हो तो StreamReader.read () या StreamReader.readexactly () का उपयोग करबनाए गए ड्राइवर को तत्काल रिटर्न के साथ निम्नलिखित तुल्यकालिक विधि प्रदान करनी चाहिए: तर्कों के साथलिखना , बंद करना, sz ।कहां:buf लिखने के लिए बफर है।बंद - लिखने के लिए पहले चरित्र के बफर पर ऑफसेट।sz - लिखने के लिए वर्णों की अनुरोधित संख्या।रिटर्न वैल्यू वास्तव में लिखे गए वर्णों की संख्या है (हो सकता है कि डिवाइस धीमा होने पर 1)। Ioctlविधि यह सुनिश्चित करती है कि यह केवल तभी कहा जाएगा जब डिवाइस डेटा प्राप्त करने के लिए तैयार हो।सभी उपकरणों को एक ioctl विधि प्रदान करनी चाहिए जो इसकी उपलब्धता की स्थिति को निर्धारित करने के लिए उपकरणों को मतदान करती है। पढ़ने / लिखने वाले ड्राइवर के लिए एक विशिष्ट उदाहरण: import io MP_STREAM_POLL_RD = const(1) MP_STREAM_POLL_WR = const(4) MP_STREAM_POLL = const(3) MP_STREAM_ERROR = const(-1) class MyIO(io.IOBase):
निम्नलिखित मिलिसटेकमर क्लास वेटिंग देरी का विवरण है : import uasyncio as asyncio import utime import io MP_STREAM_POLL_RD = const(1) MP_STREAM_POLL = const(3) MP_STREAM_ERROR = const(-1) class MillisecTimer(io.IOBase): def __init__(self): self.end = 0 self.sreader = asyncio.StreamReader(self) def __iter__(self): await self.sreader.readline() def __call__(self, ms): self.end = utime.ticks_add(utime.ticks_ms(), ms) return self def readline(self): return b'\n' def ioctl(self, req, arg): ret = MP_STREAM_ERROR if req == MP_STREAM_POLL: ret = 0 if arg & MP_STREAM_POLL_RD: if utime.ticks_diff(utime.ticks_ms(), self.end) >= 0: ret |= MP_STREAM_POLL_RD return ret
जिसका उपयोग निम्नानुसार किया जा सकता है: async def timer_test ( n ): timer = ms_timer.MillisecTimer () await timer ( 30 )
आधिकारिक uasyncio की तुलना में , asyncio.sleep_ms () का इंतजार करने की तुलना में इस तरह के कार्यान्वयन से कोई लाभ नहीं मिलता है । Fast_io का उपयोग सामान्य उपयोग पैटर्न में काफी अधिक सटीक विलंब प्रदान करता है, जब कोरटाइन शून्य विलंब की उम्मीद करते हैं।आप कॉलबैक के साथ किसी ईवेंट को संबद्ध करने के लिए I / O शेड्यूलिंग का उपयोग कर सकते हैं। यह मतदान चक्र की तुलना में अधिक कुशल है, क्योंकि ioctl के तैयार होने तक मतदान निर्धारित नहीं है । अगला, कॉलबैक स्थिति बदलने पर कॉलबैक निष्पादित होता है। import uasyncio as asyncio import io MP_STREAM_POLL_RD = const(1) MP_STREAM_POLL = const(3) MP_STREAM_ERROR = const(-1) class PinCall(io.IOBase): def __init__(self, pin, *, cb_rise=None, cbr_args=(), cb_fall=None, cbf_args=()): self.pin = pin self.cb_rise = cb_rise self.cbr_args = cbr_args self.cb_fall = cb_fall self.cbf_args = cbf_args self.pinval = pin.value() self.sreader = asyncio.StreamReader(self) loop = asyncio.get_event_loop() loop.create_task(self.run()) async def run(self): while True: await self.sreader.read(1) def read(self, _): v = self.pinval if v and self.cb_rise is not None: self.cb_rise(*self.cbr_args) return b'\n' if not v and self.cb_fall is not None: self.cb_fall(*self.cbf_args) return b'\n' def ioctl(self, req, arg): ret = MP_STREAM_ERROR if req == MP_STREAM_POLL: ret = 0 if arg & MP_STREAM_POLL_RD: v = self.pin.value() if v != self.pinval: self.pinval = v ret = MP_STREAM_POLL_RD return ret
और फिर से - आधिकारिक uasyncio पर, देरी अधिक हो सकती है। एप्लिकेशन डिज़ाइन के आधार पर, fast_io संस्करण अधिक कुशल हो सकता है।प्रदर्शन कार्यक्रम iorw.py शो पूर्ण उदाहरण। कृपया ध्यान दें कि आधिकारिक uasyncio में लेख लिखने के समय एक त्रुटि है जिसके कारण यह काम नहीं करता है । दो उपाय हैं। वर्कअराउंड दो अलग-अलग ड्राइवरों को लिखना है, एक केवल पढ़ने के लिए और एक केवल लिखने के लिए है। दूसरा है fast_io का उपयोग करना , जो इस समस्या को हल करता है।आधिकारिक uasyncio में, इनपुट / आउटपुट की योजना काफी दुर्लभ है ।6.5 पूर्ण उदाहरण: aremote.pyड्राइवर को एक अवरक्त रिमोट कंट्रोल से सिग्नल प्राप्त / डिकोड करने के लिए डिज़ाइन किया गया है। Aremote.py ड्राइवर ही । निम्नलिखित नोट एसिंको के उपयोग के बारे में महत्वपूर्ण हैं।संपर्क में व्यवधान राज्य परिवर्तन (माइक्रोसेकंड में) का समय रिकॉर्ड करता है और घटना को सेट करता है, उस समय को छोड़ देता है जब पहला राज्य परिवर्तन होता है। कोरआउट एक घटना की प्रतीक्षा करता है, डेटा पैकेट की अवधि की रिपोर्ट करता है, फिर उपयोगकर्ता द्वारा निर्दिष्ट कॉलबैक को कॉल करने से पहले संग्रहीत डेटा को डीकोड करता है। ईवेंट केउदाहरण के लिए समय बीतने से, कोरोइन को विलंब की अवधि निर्धारित करते समयकिसी भी एसिंसीओ देरी केलिए क्षतिपूर्ति करने की अनुमति मिलती है । 6.6 HTU21D पर्यावरण सेंसरड्राइवर HTU21D चिप तापमान और आर्द्रता की सही माप प्रदान करता है।दोनों डेटा तत्वों को प्राप्त करने के लिए चिप को लगभग 120 एमएस की आवश्यकता होती है। ड्राइवर अतुल्यकालिक रूप से काम करता है,डेटा पढ़ने से पहले asyncio.sleep (t) की प्राप्ति और उपयोग की पहल करता है,तापमान और आर्द्रता चर को अद्यतन करता है, जिसे किसी भी समय एक्सेस किया जा सकता है, जो चिप चालक के चलने के दौरान अन्य कोरटाइन को लॉन्च करने की अनुमति देता है।7.Tips और ट्रिक्स7.1 कार्यक्रम फ्रीज होजाता है फ्रीज आमतौर पर होता है क्योंकि कार्य रियायत के बिना अवरुद्ध है: यह पूरे सिस्टम को फ्रीज कर देगा। विकसित करते समय, एक कोरोटीन होना उपयोगी होता है जो समय-समय पर निर्मित एलईडी में बदल जाता है। यह पुष्टि करता है कि शेड्यूलर अभी भी चल रहा है।7.2 uasyncio राज्य को बचाता हैजब REPL में uasyncio का उपयोग करके प्रोग्राम शुरू करते हैं, तो शुरू के बीच एक नरम रीसेट (ctrl-D) करें। इस तथ्य के कारण कि uasyncio प्रारंभ के बीच स्थिति बनाए रखता है, अप्रत्याशित व्यवहार अगली शुरुआत में हो सकता है।7.3 कचरा संग्रहआप पहले आयात जीसी निर्दिष्ट करके एक कोरटाइन निष्पादित कर सकते हैं : gc.collect () gc.treshold ( gc.mem_free () // 4 + gc.mem_alloc ())
इसका उद्देश्य यहाँ ढेर अनुभाग में चर्चा की गई है ।7.4 परीक्षणयह सुनिश्चित करना उचित है कि डिवाइस चालक आवश्यक होने पर नियंत्रण बनाए रखता है, जो काल्पनिक कोरटाइन की एक या एक से अधिक प्रतियों को चलाकर किया जा सकता है जो संदेश मुद्रण चक्र को शुरू करते हैं और जांचते हैं कि यह अवधि के दौरान चलता है जब चालक स्टैंडबाय मोड में है: async def rr(n): while True: print('Roundrobin ', n) await asyncio.sleep(0)
उपरोक्त प्रकार के खतरे के एक उदाहरण के रूप में, उपरोक्त उदाहरण में, RecordOrientedUart __await__ विधि को मूल रूप से लिखा गया था: def __await__(self): data = b'' while not data.endswith(self.DELIMITER): while not self.uart.any(): yield from asyncio.sleep(0) data = b''.join((data, self.uart.read(self.uart.any()))) self.data = data
नतीजतन, निष्पादन पूरे रिकॉर्ड प्राप्त होने तक बढ़ाया जाता है, साथ ही साथ यह तथ्य कि uart.any () हमेशा प्राप्त वर्णों की एक गैर-संख्या को वापस कर देता है। कॉल के समय तक, सभी वर्ण पहले ही प्राप्त हो सकते हैं। बाहरी लूप का उपयोग करके इस स्थिति को हल किया जा सकता है: def __await__(self): data = b'' while not data.endswith(self.DELIMITER): yield from asyncio.sleep(0)
यह ध्यान देने योग्य हो सकता है कि यह त्रुटि स्पष्ट नहीं होती यदि फीडबैक परीक्षण का उपयोग करने के बजाय डेटा को UART को कम गति पर भेजा गया होता। वास्तविक समय प्रोग्रामिंग की खुशियों में आपका स्वागत है।7.5 सामान्य त्रुटियदि कोई फ़ंक्शन या विधि async डिफ द्वारा परिभाषित की जाती है और बाद में कहा जाता है जैसे कि यह एक नियमित (सिंक्रोनस) कॉल थी, तो MicroPython एक त्रुटि संदेश प्रदर्शित नहीं करता है। यह डिजाइन द्वारा है। आमतौर पर यह इस तथ्य की ओर जाता है कि कार्यक्रम चुपचाप सही ढंग से काम नहीं करता है: async def foo():
मेरे पास एक सुझाव है जो fast_io का उपयोग करके विकल्प 1 में स्थिति को ठीक करने का सुझाव देता है । Check_async_code.pyमॉड्यूल coroutines के संदिग्ध उपयोग के मामलों का पता लगाने की कोशिश करता है। यह पायथन 3 में लिखा गया है और एक पीसी पर काम करने के लिए बनाया गया है। इस गाइड में उल्लिखित दिशानिर्देशों के अनुसार लिखी गई लिपियों में उपयोग किया गया है, जो कि async def का उपयोग करते हुए घोषित की गई हैं । मॉड्यूल एक तर्क लेता है, स्रोत MicroPython फ़ाइल का पथ (या --help)।कृपया ध्यान दें कि यह कुछ असभ्य है और इसका उपयोग एक वाक्यविन्यास रूप से सही फ़ाइल में किया जाना है, जो डिफ़ॉल्ट रूप से शुरू नहीं होता है। सामान्य सिंटैक्स चेकिंग के लिए पाइलिंट जैसे टूल का उपयोग करें ( पाइलिंट के पास वर्तमान में यह त्रुटि नहीं है)।स्क्रिप्ट झूठी सकारात्मकता पैदा करती है। योजना के अनुसार, कोरआउट पहले स्तर की वस्तुएं हैं, उन्हें कार्यों में स्थानांतरित किया जा सकता है और डेटा संरचनाओं में संग्रहीत किया जा सकता है। कार्यक्रम के तर्क के आधार पर, आप फ़ंक्शन या इसके निष्पादन के परिणाम को बचा सकते हैं। स्क्रिप्ट इरादे को निर्धारित नहीं कर सकती है। इसका उद्देश्य उन मामलों की अनदेखी करना है जो विचार करने के लिए अन्य मामलों की पहचान करते समय सही प्रतीत होते हैं। मान लीजिए foo , जहां सह दिनचर्या के रूप में घोषित किया जाता है async डीईएफ़ : loop.run_until_complete(foo())
मुझे लगता है कि यह उपयोगी है, लेकिन सुधार हमेशा स्वागत है।सॉकेट (साथ 7.6 प्रोग्रामिंग सॉकेट )प्रोग्रामिंग सॉकेट करने के लिए दो बुनियादी दृष्टिकोण हैं uasyncio । डिफ़ॉल्ट रूप से, सॉकेट्स तब तक ब्लॉक किए जाते हैं जब तक कि निर्दिष्ट रीड या राइट ऑपरेशन पूरा नहीं हो जाता। शेड्यूलर को ब्लॉक करने से रोकने के लिए Uasyncio, सॉकेट लॉकिंग का चयन करता है। ज्यादातर मामलों में, इस तंत्र का उपयोग करना सबसे आसान है। क्लाइंट और सर्वर कोड का एक उदाहरण client_server निर्देशिका में पाया जा सकता है । उपयोगकर्ता सॉकेट को स्पष्ट रूप से मतदान करके चयन.पॉल एप्लिकेशन का उपयोग करता है ।क्लाइंट सॉकेट इसका उपयोग इस अर्थ में करते हैं कि uasyncio स्ट्रीमिंग इंजन सीधे इसका उपयोग करता है।कृपया ध्यान दें कि वर्तमान में socket.getaddrinfo अवरुद्ध है। नमूना कोड में समय कम से कम होगा, लेकिन अगर DNS लुकअप की आवश्यकता होती है, तो अवरुद्ध अवधि महत्वपूर्ण हो सकती है।सॉकेट प्रोग्रामिंग के लिए एक दूसरा तरीका गैर-अवरुद्ध सॉकेट्स का उपयोग करना है। यह जटिलता जोड़ता है, लेकिन कुछ अनुप्रयोगों में आवश्यक है, खासकर यदि कनेक्शन वाईफाई के माध्यम से है (नीचे देखें)।इस लेखन (मार्च 2019) के समय, गैर-अवरुद्ध सॉकेट्स के लिए टीएलएस समर्थन विकास के अधीन था। इसकी सटीक स्थिति अज्ञात है (मेरे लिए)।गैर-अवरुद्ध सॉकेट्स का उपयोग करने के लिए विस्तार पर कुछ ध्यान देने की आवश्यकता होती है। यदि सर्वर विलंबता के कारण गैर-अवरोधक रीड होते हैं, तो इस बात की कोई गारंटी नहीं है कि अनुरोधित डेटा के सभी (या किसी भी) वापस कर दिए जाएंगे। इसी तरह, प्रविष्टियाँ पूरी नहीं हो सकती हैं।इसलिए, अतुल्यकालिक पढ़ने और लिखने के तरीकों को पुनरावृत्ति करना चाहिए जब तक आवश्यक डेटा पढ़ा या लिखा नहीं जाता है। व्यवहार में, सर्वर आउटेज से निपटने के लिए टाइमआउट की आवश्यकता हो सकती है।एक और जटिलता यह है कि ESP32 पोर्ट में समस्याएं थीं जो त्रुटि मुक्त संचालन के लिए बहुत बुरा ब्रेक-इन की आवश्यकता थीं। मैंने परीक्षण नहीं किया है कि क्या यह अभी भी मामला है। Sock_nonblock.pyमॉड्यूलआवश्यक तरीकों को दिखाता है। यह कार्यशील डेमो नहीं है और निर्णय आवेदन पर निर्भर होने की संभावना है।7.6.1 वाईफाईकी समस्याएँ वाईफाई आउटेज का पता लगाते समय uasyncio स्ट्रीमिंग तंत्र सबसे अच्छा विकल्प नहीं है। मैंने असफल-सुरक्षित संचालन प्रदान करने और विफलताओं की स्थिति में ग्राहक को फिर से जोड़ने के लिए गैर-अवरुद्ध सॉकेट्स का उपयोग करना आवश्यक पाया।यह दस्तावेज़ उन समस्याओं का वर्णन करता है जो मुझे वाईफाई अनुप्रयोगों में आई हैं जो विस्तारित अवधि के लिए सॉकेट खोलते हैं और समाधान की रूपरेखा देते हैं।Pltcmएक मजबूत अतुल्यकालिक एमक्यूटीटी क्लाइंट प्रदान करता है जो वाईफाई विफलताओं के दौरान संदेश अखंडता प्रदान करता है। वायरलेस क्लाइंट के बीच एक सरल एसिंक्रोनस फुल-डुप्लेक्स सीरियल लिंक और गारंटीकृत संदेश डिलीवरी वाला वायर्ड सर्वर वर्णित है।7.7 इवेंट लूप कंस्ट्रक्टर के तर्कएक छोटी सी त्रुटि हो सकती है यदि आपको डिफ़ॉल्ट मान से भिन्न मान वाले ईवेंट लूप बनाने की आवश्यकता होती है। इस तरह के लूप को एसिंको का उपयोग करके किसी अन्य कोड को चलाने से पहले घोषित किया जाना चाहिए क्योंकि इस कोड में इन मूल्यों की आवश्यकता हो सकती है। अन्यथा, कोड को डिफ़ॉल्ट मानों के साथ आरंभ किया जाएगा: import uasyncio as asyncio import some_module bar = some_module.Bar()
यह देखते हुए कि एक मॉड्यूल आयात कोड को निष्पादित कर सकता है, सबसे सुरक्षित तरीका है एक घटना लूप को तुरंत uasyncio आयात करने के बाद । import uasyncio as asyncio loop = asyncio.get_event_loop(runq_len=40, waitq_len=40) import some_module bar = some_module.Bar()
अन्य कार्यक्रमों द्वारा उपयोग के लिए मॉड्यूल लिखते समय, मैं आयात पर uasyncio कोड चलाने से बचना पसंद करता हूं । फ़ंक्शन और विधियों को तर्क के रूप में इवेंट लूप की प्रतीक्षा करने के लिए लिखें। फिर सुनिश्चित करें कि केवल शीर्ष-स्तरीय एप्लिकेशन get_event_loop को कॉल करते हैं : import uasyncio as asyncio import my_module
इस मुद्दे पर यहां चर्चा की गई है ।शुरुआती लोगों के लिए 8 नोटये नोट एसिंक्रोनस कोड में शुरुआती लोगों के लिए हैं और उन समस्याओं के विवरण के साथ शुरू होते हैं जो योजनाकार हल करने की कोशिश करते हैं, साथ ही समाधानों के लिए uasyncio के दृष्टिकोण का अवलोकन देते हैं।धारा 8.5 uasyncio और _ थ्रेड मॉड्यूल के सापेक्ष गुणों पर चर्चा करता है , साथ ही आप सक्रिय शेड्यूलिंग (_thread) के साथ uasyncio कोरआउट्स का उपयोग करना क्यों पसंद कर सकते हैं ।8.1 समस्या 1: ईवेंट लूपएक सामान्य फर्मवेयर एप्लिकेशन लगातार काम करता है और एक ही समय में बाहरी घटनाओं का जवाब देना चाहिए, जिसमें एडीसी पर वोल्टेज में बदलाव, हार्डवेयर रुकावट की उपस्थिति, या यूएआरटी में प्राप्त एक प्रतीक, या सॉकेट पर उपलब्ध डेटा शामिल हो सकते हैं। ये ईवेंट असिंक्रोनस रूप से होते हैं, और कोड को उस आदेश की परवाह किए बिना जवाब देने में सक्षम होना चाहिए जिसमें वे होते हैं। इसके अलावा, समय-निर्भर कार्यों की आवश्यकता हो सकती है, जैसे कि एलईडी चमकती।ऐसा करने का स्पष्ट तरीका uasycio इवेंट लूप के साथ है । यह उदाहरण व्यावहारिक कोड नहीं है, लेकिन घटना लूप के सामान्य रूप को चित्रित करने का कार्य करता है। def event_loop(): led_1_time = 0 led_1_period = 20 led_2_time = 0 led_2_period = 30 switch_state = switch.state()
ऐसा लूप सरल उदाहरणों के लिए काम करता है, लेकिन जैसे-जैसे घटनाओं की संख्या बढ़ती है, कोड जल्दी से बोझिल हो जाता है। वे एक प्रोग्राम में अधिकांश लॉजिक को नियंत्रित ऑब्जेक्ट से जोड़ने के बजाय ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग के सिद्धांतों का उल्लंघन करते हैं। हम एक चमकती एलईडी के लिए एक वर्ग विकसित करना चाहते हैं जिसे एक मॉड्यूल में डाला जा सकता है और आयात किया जा सकता है। एलईडी चमकती करने के लिए OOP दृष्टिकोण इस तरह हो सकता है: import pyb class LED_flashable(): def __init__(self, led_no): self.led = pyb.LED(led_no) def flash(self, period): while True: self.led.toggle()
Uasyncio में अनुसूचक आपको ऐसी कक्षाएं बनाने की अनुमति देता है।8.2 समस्या 2: ब्लॉकिंग के तरीकेमान लें कि आपको सॉकेट से एक निश्चित संख्या में बाइट्स पढ़ने हैं। यदि आप डिफ़ॉल्ट रूप से अवरुद्ध सॉकेट के साथ सॉकेट (n) कहते हैं , तो यह " बाइट " होगा (अर्थात, यह तब तक समाप्त नहीं होगा) जब तक n बाइट प्राप्त नहीं हो जाते । इस अवधि के दौरान, एप्लिकेशन अन्य घटनाओं का जवाब नहीं देगा।नॉन-ब्लॉकिंग uasyncio सॉकेट का उपयोग करके , आप एक एसिंक्रोनस रीड विधि लिख सकते हैं। एक कार्य जिसे डेटा प्राप्त करने की आवश्यकता होती है (आवश्यक) उसे प्राप्त होने तक अवरुद्ध किया जाता है, लेकिन इस अवधि के दौरान अन्य कार्य किए जाएंगे, जो एप्लिकेशन को उत्तरदायी बने रहने की अनुमति देगा।8.3। Uasyncio दृष्टिकोणअगली कक्षा में एक एलईडी है जिसे चालू और बंद किया जा सकता है, और आप किसी भी गति से झपकी ले सकते हैं। LED_async आवृत्ति रन विधि का उपयोग करती है , जिसका उपयोग निरंतर संचालन के लिए किया जा सकता है। एल ई डी के व्यवहार को ऑन (), ऑफ (), और फ्लैश (सेकंड) विधियों का उपयोग करके नियंत्रित किया जा सकता है । import pyb import uasyncio as asyncio class LED_async(): def __init__(self, led_no): self.led = pyb.LED(led_no) self.rate = 0 loop = asyncio.get_event_loop() loop.create_task(self.run()) async def run(self): while True: if self.rate <= 0: await asyncio.sleep_ms(200) else: self.led.toggle() await asyncio.sleep_ms(int(500 / self.rate)) def flash(self, rate): self.rate = rate def on(self): self.led.on() self.rate = 0 def off(self): self.led.off() self.rate = 0
यह ध्यान दिया जाना चाहिए कि ऑन (), ऑफ () और फ्लैश () साधारण सिंक्रोनस तरीके हैं। वे एलईडी के व्यवहार को बदलते हैं, लेकिन तुरंत वापस लौटते हैं। निमिष "पृष्ठभूमि में होता है।" इसके बारे में अगले भाग में विस्तार से बताया गया है।वर्ग ओओपी सिद्धांत का अनुपालन करता है, जिसमें कक्षा में डिवाइस से जुड़े तर्क को संग्रहीत करना शामिल है। इसी समय, uasyncio का उपयोग यह सुनिश्चित करता है कि एप्लिकेशन अन्य घटनाओं पर प्रतिक्रिया दे सकता है जबकि एलईडी झपकी ले रहा है। नीचे दिया गया कार्यक्रम विभिन्न आवृत्तियों पर चार पाइबोड एल ई डी के साथ चमकता है , और यूएसआर बटन पर भी प्रतिक्रिया करता है, जो इसे पूरा करता है। import pyb import uasyncio as asyncio from led_async import LED_async
ईवेंट लूप के पहले उदाहरण के विपरीत, स्विच से जुड़ा तर्क एलईडी की कार्यक्षमता से अलग एक फ़ंक्शन में है। अनुसूचक शुरू करने के लिए उपयोग किए गए कोड पर ध्यान दें: loop = asyncio.get_event_loop() loop.run_until_complete(killer())
8.4 uasyncioPython 3.5 और MicroPython में नियोजन एक अतुल्यकालिक फ़ंक्शन की अवधारणा का समर्थन करता है, जिसे एक coroutine या कार्य के रूप में भी जाना जाता है। एक coroutine में कम से कम एक प्रतीक्षा विवरण शामिल होना चाहिए । async def hello(): for _ in range(10): print('Hello world.') await asyncio.sleep(1)
यह फ़ंक्शन एक-दूसरे के अंतराल पर दस बार संदेश भेजता है। जबकि फ़ंक्शन को देरी की प्रत्याशा में रोका जाता है, asyncio अनुसूचक अन्य कार्यों का प्रदर्शन करेगा, उन्हें एक साथ चलाने का भ्रम पैदा करेगा।जब कोई coroutine समस्याएँ asyncio.sleep_ms () या asyncio.sleep () का इंतजार करती हैं, तो वर्तमान कार्य को रोक दिया जाता है और एक कतार में रख दिया जाता है जो समय के अनुसार आदेश दिया जाता है और कार्य कतार के शीर्ष पर कार्य के लिए आगे बढ़ता है। कतार को इस तरह से डिज़ाइन किया गया है कि, भले ही निर्दिष्ट नींद मोड शून्य हो, अन्य प्रासंगिक कार्यों को फिर से शुरू होने तक किया जाएगा। यह "ईमानदार परिपत्र" योजना है। यह asyncio.sleep (0) लूप चलाने के लिए आम बात है।ताकि कार्य निष्पादन में देरी न करें। निम्नलिखित एक व्यस्त-प्रतीक्षा लूप है जो वैश्विक ध्वज चर सेट करने के लिए किसी अन्य कार्य की प्रतीक्षा कर रहा है । काश, यह प्रोसेसर को एकाधिकार देता है, अन्य कोराउटीन के प्रक्षेपण को रोकता है: async def bad_code(): global flag while not flag: pass
यहाँ समस्या यह है कि जब तक फ़्लैगिस फ़ॉल्स लूप शेड्यूलर को नियंत्रित नहीं करता है, तब तक कोई अन्य कार्य शुरू नहीं किया जाएगा। सही तरीका: async def good_code(): global flag while not flag: await asyncio.sleep(0)
उसी कारण से, देरी सेट करना बुरा व्यवहार है, उदाहरण के लिए, utime.sleep (1) क्योंकि यह 1 एस के लिए अन्य कार्यों को अवरुद्ध करता है; यह asyncio.sleep (1) का उपयोग करने के लिए अधिक सही है ।कृपया ध्यान दें कि uasyncio नींद और sleep_ms तरीकों से उत्पन्न देरी वास्तव में निर्दिष्ट समय से अधिक हो सकती है। यह इस तथ्य के कारण है कि देरी के दौरान अन्य कार्यों का प्रदर्शन किया जाएगा। बाद क्रियान्वयन से पहले देरी की अवधि तक फिर से शुरू है चल रहा है काम नहीं देंगे इंतजार या इस्तीफा। एक अच्छी तरह से व्यवहार किए गए कोरटाइन हमेशा प्रतीक्षा की घोषणा करेंगेनियमित अंतराल पर। जहां एक सटीक देरी की आवश्यकता होती है, खासकर यदि कोई कुछ एमएस से कम है, तो utime.sleep_us (us) का उपयोग करना आवश्यक हो सकता है ।8.5 सहयोगी, थ्रेड-आधारित शेड्यूलिंग ( _thread ) क्यों नहीं ?सह-नियोजन कोरआउट के विचार के लिए शुरुआती प्रतिक्रिया अक्सर निराशाजनक होती है। निश्चित रूप से स्ट्रीमिंग की योजना बेहतर है? यदि पायथन वर्चुअल मशीन मेरे लिए ऐसा कर सकती है तो मुझे स्पष्ट रूप से नियंत्रण क्यों देना चाहिए?जब यह एम्बेडेड सिस्टम की बात आती है, तो सहयोग मॉडल के दो फायदे हैं।पहला हल्का वजन है। बड़ी संख्या में कॉरआउट्स संभव है, क्योंकि अनुसूचित धागों के विपरीत, निलंबित कॉरआउट्स कम जगह लेते हैं।दूसरे, यह स्ट्रीमिंग शेड्यूलिंग से जुड़े कुछ सूक्ष्म मुद्दों से बचा जाता है।व्यवहार में, सहयोगी मल्टीटास्किंग का व्यापक रूप से उपयोग किया जाता है, विशेष रूप से उपयोगकर्ता इंटरफ़ेस अनुप्रयोगों में।स्ट्रीमिंग-प्लानिंग मॉडल के बचाव में, मैं एक फायदा दिखाऊंगा: अगर कोई लिखता है for x in range ( 1000000 ):
यह अन्य कार्यों को अवरुद्ध नहीं करेगा। सहयोग मॉडल मानता है कि लूप को प्रत्येक कार्य को निश्चित रूप से पुनरावृत्तियों की एक निश्चित संख्या पर नियंत्रण देना चाहिए, उदाहरण के लिए, एक coroutine में कोड डालना और समय-समय पर जारी asyncio.sleep (0) जारी करना ।काश, यह लाभ नुकसान के साथ तुलना में है। इन में से कुछ को बाधित हैंडलर लिखने के लिए प्रलेखन में वर्णित किया गया है ।। स्ट्रीमिंग शेड्यूलिंग मॉडल में, प्रत्येक थ्रेड किसी भी अन्य थ्रेड को बाधित कर सकता है, डेटा को बदल सकता है जो अन्य थ्रेड्स में उपयोग किया जा सकता है। एक नियम के रूप में, एक लॉक को ढूंढना और ठीक करना बहुत आसान है जो एक त्रुटि के कारण होता है जो कभी-कभी बहुत सूक्ष्म और शायद ही कभी सामना की गई त्रुटियों का पता लगाने की तुलना में परिणाम नहीं देता है जो स्ट्रीमिंग योजना के साथ एक मॉडल के ढांचे में लिखे गए कोड में हो सकता है।सीधे शब्दों में कहें, अगर आप एक माइक्रोप्थॉन कोरटाइन लिखते हैं, तो आप यह सुनिश्चित कर सकते हैं कि चर को अचानक किसी अन्य coroutine द्वारा नहीं बदला जाएगा: जब तक यह asyncio.sleep (0) का इंतजार नहीं करता, तब तक आपका coroutine पूर्ण नियंत्रण रखता है ।ध्यान रखें कि बाधा हैंडलर प्रीमेप्टिव हैं। यह हार्डवेयर और सॉफ्टवेयर दोनों पर लागू होता है जो आपके कोड में कहीं भी हो सकता है।स्ट्रीमिंग योजना के मुद्दों की एक विस्तृत चर्चा यहाँ मिल सकती है ।8.6 सहभागितागैर-तुच्छ अनुप्रयोगों में, कोरटाइन को बातचीत करनी चाहिए। पारंपरिक पायथन विधियों का उपयोग किया जा सकता है । इनमें वैश्विक चर का उपयोग करना या कोरटाइन को ऑब्जेक्ट विधियों के रूप में घोषित करना शामिल है: वे उदाहरण चर साझा कर सकते हैं। वैकल्पिक रूप से, एक उत्परिवर्तित वस्तु को कोरटाइन के तर्क के रूप में पारित किया जा सकता है।स्ट्रीमिंग-प्लानिंग मॉडल को यह सुनिश्चित करने के लिए विशेषज्ञों की आवश्यकता होती है कि कक्षाएं एक सुरक्षित कनेक्शन प्रदान करती हैं; एक सहयोग मॉडल में, यह शायद ही कभी आवश्यक है।8.7। पोल ( मतदान )ऐसे accelerometer एक के रूप में कुछ हार्डवेयर डिवाइस Pyboard , बीच में आता है का समर्थन नहीं करते हैं, और इसलिए सर्वेक्षण में शामिल किया जाना चाहिए (अर्थात सावधिक जांच)। मतदान का उपयोग बाधित हैंडलर के संयोजन में भी किया जा सकता है: बाधा हैंडलर उपकरण बनाए रखता है और एक ध्वज सेट करता है। कॉरटीन ध्वज को पोल करता है - यदि यह सेट है, तो डेटा संसाधित होता है और ध्वज रीसेट हो जाता है। इवेंट क्लास का उपयोग करने के लिए सबसे अच्छा तरीका है ।