asyncio --- مجدول الإدخال/الإخراج غير المتزامن

توفر هذه الوحدة مجدولًا للمهام المتعددة التعاونية لكوروتينات async/await، إلى جانب أدوات أولية للمزامنة (الأقفال والأحداث) وشبكات TCP غير الحاجبة عبر قارئات وكاتبات التدفق. تُشغَّل المهام بشكل متزامن على حلقة أحداث واحدة؛ تتنازل المهمة قيد التشغيل عن التحكم للحلقة باستخدام await.

مثال:

import asyncio

async def blink(led, period_ms):
    while True:
        led.on()
        await asyncio.sleep_ms(5)
        led.off()
        await asyncio.sleep_ms(period_ms)

async def main(led1, led2):
    asyncio.create_task(blink(led1, 700))
    asyncio.create_task(blink(led2, 400))
    await asyncio.sleep_ms(10_000)

# Running on an OpenMV Cam
from machine import LED
asyncio.run(main(LED(1), LED(2)))

الدوال الأساسية

asyncio.create_task(coro: Coroutine) Task

إنشاء مهمة جديدة من الكوروتين المعطى وجدولتها للتشغيل.

تُعيد كائن Task المقابل.

asyncio.current_task() Task

تُعيد كائن Task المرتبط بالمهمة قيد التشغيل حاليًا.

asyncio.run(coro: Coroutine) Any

إنشاء مهمة جديدة من الكوروتين المعطى وتشغيلها حتى تكتمل.

تُعيد القيمة التي يُرجعها coro.

asyncio.sleep(t: float) None

النوم لمدة t ثانية (يمكن أن يكون عددًا عشريًا).

هذه دالة كوروتين.

asyncio.sleep_ms(t: int) None

النوم لمدة t بالمللي ثانية.

هذه دالة كوروتين، وامتداد خاص بـ MicroPython.

دوال إضافية

asyncio.wait_for(awaitable: Awaitable, timeout: float) Any

الانتظار حتى يكتمل awaitable، ولكن إلغاؤه إذا استغرق وقتًا أطول من timeout ثانية. إذا لم يكن awaitable مهمة فسيتم إنشاء مهمة منه.

إذا حدثت مهلة، فإنه يلغي المهمة ويرفع asyncio.TimeoutError: ينبغي أن يلتقط المُستدعِي هذا. تتلقى المهمة asyncio.CancelledError التي قد يتم تجاهلها أو التقاطها باستخدام try...except أو try...finally لتشغيل شفرة التنظيف.

تُعيد القيمة المُرجَعة من awaitable.

هذه دالة كوروتين.

asyncio.wait_for_ms(awaitable: Awaitable, timeout: int) Any

مشابه لـ wait_for() ولكن timeout عدد صحيح بالمللي ثانية.

هذه دالة كوروتين، وامتداد خاص بـ MicroPython.

asyncio.gather(*awaitables, return_exceptions: bool = False) List

تشغيل جميع awaitables بشكل متزامن. تتم ترقية أي من awaitables التي ليست مهامًا إلى مهام.

تُعيد قائمة بالقيم المُرجَعة لجميع awaitables.

هذه دالة كوروتين.

class Task

class asyncio.Task

يغلّف هذا الكائن كوروتينًا داخل مهمة قيد التشغيل. يمكن الانتظار على المهام باستخدام await task، الذي سينتظر اكتمال المهمة ويُعيد القيمة المُرجَعة من المهمة.

لا ينبغي إنشاء المهام مباشرةً، بل استخدم create_task() لإنشائها.

cancel() None

إلغاء المهمة عن طريق حقن asyncio.CancelledError فيها. قد تتجاهل المهمة هذا الاستثناء. يمكن تشغيل شفرة التنظيف عن طريق التقاطه، أو عبر try ... finally.

class Event

class asyncio.Event

إنشاء حدث جديد يمكن استخدامه لمزامنة المهام. تبدأ الأحداث في الحالة الممسوحة.

is_set() bool

تُعيد True إذا كان الحدث مضبوطًا، وFalse خلاف ذلك.

set() None

ضبط الحدث. ستتم جدولة أي مهام تنتظر على الحدث للتشغيل.

ملاحظة: يجب استدعاء هذا من داخل مهمة. ليس من الآمن استدعاؤه من IRQ أو دالة رد نداء للمجدول أو خيط آخر. انظر ThreadSafeFlag.

clear() None

مسح الحدث.

wait() None

الانتظار حتى يتم ضبط الحدث. إذا كان الحدث مضبوطًا بالفعل فإنه يعود فورًا.

هذه دالة كوروتين.

class ThreadSafeFlag

class asyncio.ThreadSafeFlag

إنشاء راية جديدة يمكن استخدامها لمزامنة مهمة مع شفرة تعمل خارج حلقة asyncio، مثل الخيوط الأخرى أو IRQs أو دوال رد نداء المجدول. تبدأ الرايات في الحالة الممسوحة.

set() None

ضبط الراية. إذا كانت هناك مهمة تنتظر على الراية، فستتم جدولتها للتشغيل.

clear() None

مسح الراية. يمكن استخدام هذا للتأكد من أن راية ربما تكون قد ضُبطت سابقًا أصبحت ممسوحة قبل الانتظار عليها.

wait() None

الانتظار حتى يتم ضبط الراية. إذا كانت الراية مضبوطة بالفعل فإنها تعود فورًا. تُعاد الراية تلقائيًا إلى حالتها الأصلية عند العودة من wait.

يمكن لمهمة واحدة فقط في كل مرة الانتظار على راية.

هذه دالة كوروتين.

class Lock

class asyncio.Lock

إنشاء قفل جديد يمكن استخدامه لتنسيق المهام. تبدأ الأقفال في الحالة غير المقفلة.

بالإضافة إلى الطرق أدناه، يمكن استخدام الأقفال في عبارة async with.

locked() bool

تُعيد True إذا كان القفل مقفلًا، وFalse خلاف ذلك.

acquire() bool

الانتظار حتى يكون القفل في الحالة غير المقفلة ثم قفله بطريقة ذرّية. يمكن لمهمة واحدة فقط الحصول على القفل في أي وقت.

هذه دالة كوروتين.

release() None

تحرير القفل. إذا كانت هناك أي مهام تنتظر على القفل فستتم جدولة المهمة التالية في الطابور للتشغيل ويبقى القفل مقفلًا. خلاف ذلك، لا توجد مهام تنتظر ويصبح القفل غير مقفل.

اتصالات تدفق TCP

asyncio.open_connection(host: str, port: int, ssl: ssl.SSLContext | bool | None = None) Tuple[Stream, Stream]

فتح اتصال TCP بـ host وport المعطيين. سيتم حل عنوان host باستخدام socket.getaddrinfo()، وهو حاليًا استدعاء حاجب. إذا كان ssl كائن ssl.SSLContext، فسيُستخدم هذا السياق لإنشاء النقل؛ وإذا كان ssl يساوي True، فسيُستخدم سياق افتراضي.

تُعيد زوجًا من التدفقات: تدفق قارئ وتدفق كاتب. سترفع OSError خاصًا بالمقبس إذا تعذّر حل المضيف أو تعذّر إجراء الاتصال.

هذه دالة كوروتين.

asyncio.start_server(callback: Callable, host: str, port: int, backlog: int = 5, ssl: ssl.SSLContext | None = None) Server

بدء خادم TCP على host وport المعطيين. سيتم استدعاء callback مع الاتصالات الواردة والمقبولة، وسيُمرَّر إليه وسيطان: تدفق قارئ وتدفق كاتب للاتصال.

إذا كان ssl كائن ssl.SSLContext، فسيُستخدم هذا السياق لإنشاء النقل.

تُعيد كائن Server.

هذه دالة كوروتين.

class asyncio.Stream

يمثّل هذا اتصال تدفق TCP. لتقليل الشفرة، تنفّذ هذه الفئة كلًا من القارئ والكاتب، ويشير كل من StreamReader وStreamWriter إلى هذه الفئة كاسم بديل.

get_extra_info(v: str) Any

الحصول على معلومات إضافية حول التدفق، يحددها v. القيم الصالحة لـ v هي: peername.

close() None

إغلاق التدفق.

wait_closed() None

الانتظار حتى يُغلق التدفق.

هذه دالة كوروتين.

read(n: int = -1) bytes

قراءة ما يصل إلى n بايت وإعادتها. إذا لم يُقدَّم n أو كان -1 فاقرأ جميع البايتات حتى EOF. ستكون القيمة المُعادة كائن بايت فارغًا إذا تمت مصادفة EOF قبل قراءة أي بايتات.

هذه دالة كوروتين.

readinto(buf: bytearray | memoryview) int

قراءة ما يصل إلى n بايت في buf حيث يساوي n طول buf.

إعادة عدد البايتات المقروءة في buf.

هذه دالة كوروتين، وامتداد خاص بـ MicroPython.

readexactly(n: int) bytes

قراءة n بايت بالضبط وإعادتها ككائن بايت.

ترفع استثناء EOFError إذا انتهى التدفق قبل قراءة n بايت.

هذه دالة كوروتين.

readline() bytes

قراءة سطر وإعادته.

هذه دالة كوروتين.

write(buf: bytes) None

تراكم buf في مخزن الإخراج المؤقت. تُفرَّغ البيانات فقط عند استدعاء Stream.drain(). يُوصى باستدعاء Stream.drain() فور استدعاء هذه الدالة.

drain() None

تفريغ (كتابة) جميع بيانات الإخراج المخزّنة مؤقتًا إلى التدفق.

هذه دالة كوروتين.

class asyncio.Server

يمثّل هذا فئة الخادم المُعادة من start_server(). يمكن استخدامها في عبارة async with لإغلاق الخادم عند الخروج.

close() None

إغلاق الخادم.

wait_closed() None

الانتظار حتى يُغلق الخادم.

هذه دالة كوروتين.

حلقة الأحداث

asyncio.get_event_loop() Loop

إعادة حلقة الأحداث المستخدمة لجدولة المهام وتشغيلها. انظر Loop.

asyncio.new_event_loop() Loop

إعادة ضبط حلقة الأحداث وإعادتها.

ملاحظة: بما أن MicroPython يحتوي على حلقة أحداث واحدة فقط، فإن هذه الدالة تعيد ضبط حالة الحلقة فحسب، ولا تنشئ حلقة جديدة.

class asyncio.Loop

يمثّل هذا الكائن الذي يجدول المهام ويشغّلها. لا يمكن إنشاؤه، استخدم get_event_loop() بدلًا من ذلك.

create_task(coro: Coroutine) Task

إنشاء مهمة من coro المعطى وإعادة كائن Task الجديد.

run_forever() None

تشغيل حلقة الأحداث حتى يتم استدعاء stop().

run_until_complete(awaitable: Awaitable) Any

تشغيل awaitable المعطى حتى يكتمل. إذا لم يكن awaitable مهمة فستتم ترقيته إلى مهمة.

stop() None

إيقاف حلقة الأحداث.

close() None

إغلاق حلقة الأحداث.

set_exception_handler(handler: Callable) None

ضبط معالج الاستثناءات الذي يُستدعى عندما ترفع مهمة استثناءً لم يتم التقاطه. ينبغي أن يقبل handler وسيطين: (loop, context).

get_exception_handler() Callable | None

الحصول على معالج الاستثناءات الحالي. تُعيد المعالج، أو None إذا لم يتم تعيين معالج مخصص.

default_exception_handler(context: dict) None

معالج الاستثناءات الافتراضي الذي يُستدعى.

call_exception_handler(context: dict) None

استدعاء معالج الاستثناءات الحالي. يُمرَّر الوسيط context عبره وهو قاموس يحتوي على المفاتيح: 'message' و'exception' و'future'.