select --- الانتظار للأحداث على مجموعة من التدفقات¶
توفّر هذه الوحدة دوالاً للانتظار بكفاءة حتى يصبح تدفق واحد أو أكثر من التدفقات (كائنات شبيهة بالملفات تُنفّذ بروتوكول التدفق، مثل المقابس وUARTs وكائنات الإدخال/الإخراج الأخرى) جاهزاً للقراءة أو الكتابة، بدلاً من الانتظار المشغول أو الحجب على كائن واحد.
كائن poll هو الواجهة المُوصى بها: فهو يتوسّع لعدد كبير من التدفقات وخالٍ من التخصيص عند استخدامه عبر poll.ipoll(). أما الدالة select() على مستوى الوحدة فهي واجهة توافق أقل كفاءة.
مثال باستخدام كائن poll
import select
poller = select.poll()
poller.register(uart, select.POLLIN)
while True:
# Wait up to 1000 ms for the UART to have data.
for obj, event in poller.poll(1000):
if event & select.POLLIN:
print(obj.read())
مثال باستخدام الدالة select() على مستوى الوحدة:
import select
# Wait up to 1 second for the socket to become readable.
rlist, wlist, xlist = select.select([sock], [], [], 1.0)
if rlist:
data = sock.recv(100)
الدوال¶
- select.select(rlist: List, wlist: List, xlist: List, timeout: float | None = None) Tuple[List, List, List]¶
ينتظر حتى يصبح كائن تدفق واحد أو أكثر من الكائنات المُعطاة جاهزاً، أو حتى تنقضي مهلة timeout.
rlist هي قائمة بالكائنات المراد مراقبتها لقابلية القراءة.
wlist هي قائمة بالكائنات المراد مراقبتها لقابلية الكتابة.
xlist هي قائمة بالكائنات المراد مراقبتها لحالة خطأ أو انقطاع.
timeout هو الحد الأقصى للوقت المراد الانتظار له، بالثواني (يُقبل عدد عشري). إذا حُذِف أو كان
Noneفإن الاستدعاء يحجب إلى أجل غير مسمى؛ أما0فيُرجِع فوراً (استطلاع غير حاجب).
يُرجِع صفاً ثلاثياً من القوائم
(rlist, wlist, xlist). كل قائمة مُرجَعة هي المجموعة الفرعية من قائمة الدخل المقابلة التي تحتوي على الكائنات التي أصبحت جاهزة للقراءة، أو جاهزة للكتابة، أو أشارت إلى خطأ/انقطاع، على التوالي. إذا انقضت مهلة timeout دون أن يكون أي شيء جاهزاً، تكون القوائم الثلاث جميعها فارغة.هذه الدالة أقل كفاءة من
poll(فهي تعيد بناء مجموعة الاستطلاع الداخلية في كل استدعاء)؛ استخدمpollبدلاً منها حيثما أمكن.
الثوابت¶
- select.POLLERR: int¶
حدثت حالة خطأ على التدفق. هذا حدث غير مطلوب: تُبلِّغ عنه
poll.poll()/poll.ipoll()حتى لو لم يُطلَب في eventmask، ولا يصحّ تمريره كـ eventmask للدخل.
- select.POLLHUP: int¶
انقطع التدفق / تم فصله. هذا حدث غير مطلوب: تُبلِّغ عنه
poll.poll()/poll.ipoll()حتى لو لم يُطلَب في eventmask، ولا يصحّ تمريره كـ eventmask للدخل.
الأصناف¶
- class select.poll¶
ينشئ كائن استطلاع يحتفظ بمجموعة من التدفقات المسجّلة (أو أي كائنات تكشف بروتوكول التدفق) وينتظر بكفاءة حتى يصبح واحد أو أكثر منها قابلاً للقراءة أو الكتابة أو يشير إلى حالة استثنائية.
تُضاف التدفقات بـ
register()، وتُزال بـunregister()، ويمكن تغيير مجموعة الأحداث المراد مراقبتها بـmodify(). بمجرد التهيئة، استدعِpoll()للحجب حتى يصبح شيء ما جاهزاً (أو تنقضي مهلة)، أوipoll()للحصول على متغير قائم على المُكرِّر وخالٍ من التخصيص.- register(obj: Any, eventmask: int = select.POLLIN | select.POLLOUT) None¶
يسجّل التدفق obj للاستطلاع، مراقباً الأحداث المُعطاة بواسطة eventmask (وهي عملية OR المنطقية لما يلي):
select.POLLIN-- تتوفّر بيانات للقراءةselect.POLLOUT-- يمكن للتدفق قبول مزيد من البيانات للكتابة
eventmask يكون افتراضياً
select.POLLIN | select.POLLOUT.select.POLLHUPوselect.POLLERRغير صالحَين في eventmask للدخل -- فهما حدثان غير مطلوبَين تُبلِّغ عنهماpoll()/ipoll()بغض النظر عما إذا طُلِبا (وهذا يطابق دلالات POSIX).لا بأس باستدعاء هذه الطريقة أكثر من مرة لنفس obj: فالاستدعاء اللاحق يحدّث قناع أحداث obj، ويتصرّف مثل
modify().
- unregister(obj: Any) None¶
يزيل obj من مجموعة التدفقات المسجّلة. وليس من الخطأ إلغاء تسجيل obj غير مسجّل حالياً (ليس للاستدعاء أي تأثير في تلك الحالة).
- modify(obj: Any, eventmask: int) None¶
يغيّر قناع الأحداث لـ obj مسجّل بالفعل إلى eventmask. يُطلِق
OSErrorمعerrno.ENOENTإذا لم يكن obj مسجّلاً.
- poll(timeout: int = -1, /) List[Tuple]¶
يحجب حتى يصبح تدفق مسجّل واحد على الأقل جاهزاً أو يشير إلى حالة استثنائية، ثم يُرجِع قائمة التدفقات التي أُطلِقت.
timeout هو الحد الأقصى للوقت المراد الانتظار له بالـ ملي ثانية. إذا حُذِف أو كان
-1فإن الاستدعاء يحجب إلى أجل غير مسمى؛ أما0فيُرجِع فوراً (استطلاع غير حاجب).يُرجِع قائمة من الصفوف
(obj, event, ...)، صف واحد لكل تدفق أُطلِق.objهو التدفق المسجّل وeventهو عملية OR على مستوى البتات لراياتselect.POLLIN/select.POLLOUT/select.POLLERR/select.POLLHUPالتي حدثت. قد يحتوي كل صف على عناصر إضافية مُحدَّدة من قبل التنفيذ، لذا لا تفترض أن طوله 2 بالضبط. إذا انقضت مهلة timeout دون أن يكون أي شيء جاهزاً، تُرجَع قائمة فارغة.قد تُرجَع
select.POLLHUPوselect.POLLERRفي أي وقت (حتى لو لم تُطلَب) ويجب التعامل معها -- عادةً بإلغاء تسجيل التدفق المتأثر وإغلاقه -- وإلا فإن الاستدعاءات اللاحقة ستظل تُرجِع فوراً مع ضبط هاتين الرايتين لذلك التدفق.يُضمَن تشغيل أي دوال رد نداء مجدولة معلّقة قبل الدخول إلى حلقة الاستطلاع.
الاختلاف عن CPython
قد تحتوي الصفوف المُرجَعة على أكثر من عنصرين، كما هو موضّح أعلاه.
- ipoll(timeout: int = -1, flags: int = 0, /) Iterator[Tuple]¶
مثل
poll()، ولكن بدلاً من بناء قائمة فإنها تُرجِع مُكرِّراً يُنتِج صفاً واحداً(obj, event, ...)في كل مرة. هذا يتجنّب التخصيص في كل استدعاء، وهو أمر مهم لمجدولات الإدخال/الإخراج غير المتزامنة.الصف المُنتَج مملوك من قبل المُستدعَى: فهو يُعاد استخدامه (يُكتب فوقه) في التكرار التالي، لذا يجب استهلاك محتوياته داخل جسم الحلقة ويجب عدم تخزين الإشارات إليه.
timeout له نفس المعنى كما في
poll(). إذا كان flags يساوي1، يُستخدم سلوك الإطلاق لمرة واحدة: فالتدفق الذي أُطلِق حدثه يُمسح قناع أحداثه تلقائياً (وهو ما يكافئpoll.modify(obj, 0))، فلا يُبلَّغ عن أي أحداث أخرى له حتى يُضبط قناعه مرة أخرى بـmodify().يُضمَن تشغيل أي دوال رد نداء مجدولة معلّقة قبل الدخول إلى حلقة الاستطلاع.
الاختلاف عن CPython
هذه الطريقة هي امتداد خاص بـ MicroPython.