select --- รอเหตุการณ์บน stream ชุดหนึ่ง

โมดูลนี้มีฟังก์ชันสำหรับรอจนกว่า streams หนึ่งรายการหรือมากกว่า (ออบเจกต์คล้ายไฟล์ที่ใช้งาน stream protocol เช่น socket, UART และออบเจกต์ I/O อื่นๆ) จะพร้อมสำหรับการอ่านหรือเขียน แทนที่จะต้องวน busy-wait หรือ block บนออบเจกต์เดียว

ออบเจกต์ poll คือ interface ที่แนะนำ: รองรับ stream จำนวนมากและไม่ต้องจัดสรรหน่วยความจำเมื่อใช้ผ่าน poll.ipoll() ฟังก์ชัน select() ระดับโมดูลเป็น interface เพื่อความเข้ากันได้ที่มีประสิทธิภาพน้อยกว่า

ตัวอย่างการใช้ออบเจกต์ 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]

รอจนกว่า stream object หนึ่งรายการหรือมากกว่าจะพร้อม หรือจนกว่า timeout จะหมดอายุ

  • rlist คือรายการออบเจกต์ที่จะตรวจสอบว่าพร้อมอ่าน

  • wlist คือรายการออบเจกต์ที่จะตรวจสอบว่าพร้อมเขียน

  • xlist คือรายการออบเจกต์ที่จะตรวจสอบว่าเกิดข้อผิดพลาดหรือสภาวะ hang-up

  • timeout คือเวลาสูงสุดที่จะรอ ในหน่วยวินาที (รับค่า float ได้) หากละเว้นหรือเป็น None การเรียกจะ block อย่างไม่มีกำหนด; 0 จะคืนค่าทันที (non-blocking poll)

คืนค่าเป็น tuple 3 รายการ (rlist, wlist, xlist) แต่ละรายการที่คืนกลับมาคือส่วนย่อยของรายการอินพุตที่สอดคล้องกัน ซึ่งประกอบด้วยออบเจกต์ที่พร้อมอ่าน พร้อมเขียน หรือส่งสัญญาณข้อผิดพลาด/hang-up ตามลำดับ หาก timeout หมดลงโดยไม่มีอะไรพร้อม ทั้งสามรายการจะว่างเปล่า

ฟังก์ชันนี้มีประสิทธิภาพน้อยกว่า poll (เนื่องจากสร้าง poll set ภายในใหม่ทุกครั้งที่เรียก) ใช้ poll แทนเมื่อเป็นไปได้

ค่าคงที่

select.POLLIN: int

มีข้อมูลพร้อมอ่านจาก stream

select.POLLOUT: int

stream สามารถรับข้อมูลเพิ่มเติมสำหรับการเขียน

select.POLLERR: int

เกิดสภาวะข้อผิดพลาดบน stream นี่คือเหตุการณ์ unsolicited: มีการรายงานโดย poll.poll() / poll.ipoll() แม้ว่าจะไม่ได้ขอใน eventmask และไม่ถูกต้องที่จะส่งเป็น eventmask อินพุต

select.POLLHUP: int

stream ถูก hang up / ตัดการเชื่อมต่อ นี่คือเหตุการณ์ unsolicited: มีการรายงานโดย poll.poll() / poll.ipoll() แม้ว่าจะไม่ได้ขอใน eventmask และไม่ถูกต้องที่จะส่งเป็น eventmask อินพุต

คลาส

class select.poll

สร้างออบเจกต์ polling ที่รักษาชุด stream ที่ลงทะเบียนไว้ (หรือออบเจกต์ใดๆ ที่เปิดเผย stream protocol) และรอจนกว่าหนึ่งรายการหรือมากกว่าจะพร้อมอ่าน พร้อมเขียน หรือส่งสัญญาณสภาวะพิเศษอย่างมีประสิทธิภาพ

เพิ่ม stream ด้วย register() ลบออกด้วย unregister() และสามารถเปลี่ยนชุดเหตุการณ์ที่ต้องการติดตามได้ด้วย modify() เมื่อกำหนดค่าแล้ว ให้เรียก poll() เพื่อ block จนกว่าบางอย่างจะพร้อม (หรือ timeout หมดลง) หรือ ipoll() สำหรับตัวแปรที่ใช้ iterator โดยไม่ต้องจัดสรรหน่วยความจำ

register(obj: Any, eventmask: int = select.POLLIN | select.POLLOUT) None

ลงทะเบียน stream obj สำหรับ polling โดยตรวจสอบเหตุการณ์ตาม eventmask (OR แบบตรรกะของ):

  • select.POLLIN -- มีข้อมูลพร้อมอ่าน

  • select.POLLOUT -- stream สามารถรับข้อมูลเพิ่มเติมสำหรับเขียน

eventmask มีค่าเริ่มต้นเป็น select.POLLIN | select.POLLOUT

select.POLLHUP และ select.POLLERR ไม่ถูกต้อง ในฐานะ eventmask อินพุต เนื่องจากเป็นเหตุการณ์ unsolicited ที่รายงานโดย poll() / ipoll() โดยไม่คำนึงว่าจะถูกขอหรือไม่ (ซึ่งตรงกับ POSIX semantics)

สามารถเรียกเมธอดนี้มากกว่าหนึ่งครั้งสำหรับ obj เดียวกันได้: การเรียกครั้งถัดไปจะอัปเดต event mask ของ obj โดยทำงานเหมือน modify()

unregister(obj: Any) None

ลบ obj ออกจากชุด stream ที่ลงทะเบียนไว้ ไม่ถือเป็นข้อผิดพลาดในการยกเลิกการลงทะเบียน obj ที่ไม่ได้ลงทะเบียนอยู่ในปัจจุบัน (การเรียกจะไม่มีผลในกรณีนั้น)

modify(obj: Any, eventmask: int) None

เปลี่ยน event mask สำหรับ obj ที่ลงทะเบียนแล้วเป็น eventmask จะ raise OSError ด้วย errno.ENOENT หาก obj ไม่ได้ลงทะเบียน

poll(timeout: int = -1, /) List[Tuple]

หยุดรอจนกว่า stream ที่ลงทะเบียนอย่างน้อยหนึ่งรายการจะพร้อมหรือส่งสัญญาณสภาวะพิเศษ จากนั้นคืนค่ารายการ stream ที่ถูกเรียก

timeout คือเวลาสูงสุดที่จะรอในหน่วย มิลลิวินาที หากละเว้นหรือเป็น -1 การเรียกจะ block อย่างไม่มีกำหนด; 0 จะคืนค่าทันที (non-blocking poll)

คืนค่าเป็นรายการ tuple (obj, event, ...) หนึ่งรายการต่อ stream ที่ถูกเรียก obj คือ stream ที่ลงทะเบียนไว้ และ event คือ OR แบบบิตของแฟล็ก select.POLLIN / select.POLLOUT / select.POLLERR / select.POLLHUP ที่เกิดขึ้น แต่ละ tuple อาจมีองค์ประกอบเพิ่มเติมที่กำหนดโดย implementation ดังนั้นอย่าสมมติว่ามีความยาวเท่ากับ 2 พอดี หาก timeout หมดลงโดยไม่มีอะไรพร้อม จะคืนค่ารายการว่าง

select.POLLHUP และ select.POLLERR อาจถูกคืนค่าได้ทุกเมื่อ (แม้ว่าจะไม่ได้ขอ) และต้องดำเนินการ โดยทั่วไปคือยกเลิกการลงทะเบียนและปิด stream ที่ได้รับผลกระทบ มิฉะนั้นการเรียกครั้งต่อๆ ไปจะยังคงคืนค่าทันทีโดยมีแฟล็กเหล่านี้ตั้งค่าสำหรับ stream นั้น

คอลแบ็กที่กำหนดเวลาไว้ทั้งหมดที่รอดำเนินการจะรับประกันว่าจะทำงานก่อนที่จะเข้าสู่ polling loop

ความแตกต่างจาก CPython

tuple ที่คืนค่าอาจมีมากกว่า 2 องค์ประกอบตามที่อธิบายไว้ข้างต้น

ipoll(timeout: int = -1, flags: int = 0, /) Iterator[Tuple]

เหมือนกับ poll() แต่แทนที่จะสร้างรายการ จะคืนค่า iterator ที่ yield tuple (obj, event, ...) ทีละรายการ ซึ่งหลีกเลี่ยงการจัดสรรหน่วยความจำในแต่ละการเรียก ซึ่งสำคัญสำหรับ asynchronous I/O scheduler

tuple ที่ yield เป็น callee-owned: มีการนำกลับมาใช้ซ้ำ (เขียนทับ) ในการวนซ้ำครั้งต่อไป ดังนั้นต้องบริโภคเนื้อหาภายใน loop body และต้องไม่เก็บ reference ไว้

timeout มีความหมายเหมือนกับใน poll() หาก flags เป็น 1 จะใช้พฤติกรรม one-shot: stream ที่เหตุการณ์เกิดขึ้นจะถูกล้าง event mask โดยอัตโนมัติ (เทียบเท่ากับ poll.modify(obj, 0)) ดังนั้นจะไม่มีการรายงานเหตุการณ์เพิ่มเติมจนกว่าจะตั้ง mask ใหม่ด้วย modify()

คอลแบ็กที่กำหนดเวลาไว้ทั้งหมดที่รอดำเนินการจะรับประกันว่าจะทำงานก่อนที่จะเข้าสู่ polling loop

ความแตกต่างจาก CPython

เมธอดนี้เป็นส่วนขยายของ MicroPython