select --- chờ đợi sự kiện trên một tập hợp luồng¶
Module này cung cấp các hàm để chờ đợi hiệu quả cho đến khi một hoặc nhiều luồng (các đối tượng giống tệp thực thi giao thức luồng, như socket, UART và các đối tượng I/O khác) sẵn sàng để đọc hoặc ghi, thay vì busy-waiting hoặc chặn trên một đối tượng duy nhất.
Đối tượng poll là giao diện được khuyến nghị: nó có thể mở rộng cho nhiều luồng và không cấp phát bộ nhớ khi sử dụng qua poll.ipoll(). Hàm select() ở cấp module là một giao diện tương thích kém hiệu quả hơn.
Ví dụ sử dụng đối tượng 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())
Ví dụ sử dụng hàm select() ở cấp module:
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)
Các hàm¶
- select.select(rlist: List, wlist: List, xlist: List, timeout: float | None = None) Tuple[List, List, List]¶
Chờ cho đến khi một hoặc nhiều đối tượng luồng đã cho sẵn sàng, hoặc cho đến khi timeout hết hạn.
rlist là danh sách các đối tượng cần giám sát để đọc.
wlist là danh sách các đối tượng cần giám sát để ghi.
xlist là danh sách các đối tượng cần giám sát để phát hiện lỗi hoặc tình trạng treo.
timeout là thời gian chờ tối đa, tính bằng giây (chấp nhận số thực). Nếu bị bỏ qua hoặc là
None, cuộc gọi sẽ chặn vô thời hạn;0trả về ngay lập tức (một lần thăm dò không chặn).
Trả về một tuple 3 phần tử gồm các danh sách
(rlist, wlist, xlist). Mỗi danh sách trả về là tập con của danh sách đầu vào tương ứng chứa các đối tượng đã sẵn sàng để đọc, sẵn sàng để ghi, hoặc đã báo hiệu lỗi/treo tương ứng. Nếu timeout hết mà không có gì sẵn sàng, cả ba danh sách đều trống.Hàm này kém hiệu quả hơn
poll(nó xây dựng lại tập thăm dò nội bộ mỗi lần gọi); hãy sử dụngpollthay thế khi có thể.
Các hằng số¶
- select.POLLERR: int¶
Đã xảy ra điều kiện lỗi trên luồng. Đây là một sự kiện không được yêu cầu: nó được báo cáo bởi
poll.poll()/poll.ipoll()ngay cả khi không được yêu cầu trong eventmask, và không hợp lệ khi truyền nó như một eventmask đầu vào.
- select.POLLHUP: int¶
Luồng đã bị treo / ngắt kết nối. Đây là một sự kiện không được yêu cầu: nó được báo cáo bởi
poll.poll()/poll.ipoll()ngay cả khi không được yêu cầu trong eventmask, và không hợp lệ khi truyền nó như một eventmask đầu vào.
Các lớp¶
- class select.poll¶
Tạo một đối tượng thăm dò duy trì một tập hợp các luồng đã đăng ký (hoặc bất kỳ đối tượng nào cung cấp giao thức luồng) và chờ đợi hiệu quả cho đến khi một hoặc nhiều trong số chúng có thể đọc, ghi, hoặc báo hiệu điều kiện ngoại lệ.
Các luồng được thêm vào bằng
register(), xóa bằngunregister(), và tập hợp các sự kiện cần theo dõi có thể được thay đổi bằngmodify(). Sau khi cấu hình, hãy gọipoll()để chặn cho đến khi có gì đó sẵn sàng (hoặc hết thời gian chờ), hoặcipoll()để có biến thể dựa trên iterator không cấp phát bộ nhớ.- register(obj: Any, eventmask: int = select.POLLIN | select.POLLOUT) None¶
Đăng ký luồng obj để thăm dò, theo dõi các sự kiện được xác định bởi eventmask (phép OR logic của):
select.POLLIN-- có dữ liệu để đọcselect.POLLOUT-- luồng có thể chấp nhận thêm dữ liệu để ghi
eventmask mặc định là
select.POLLIN | select.POLLOUT.select.POLLHUPvàselect.POLLERRkhông hợp lệ trong eventmask đầu vào -- chúng là các sự kiện không được yêu cầu được báo cáo bởipoll()/ipoll()bất kể chúng có được yêu cầu hay không (điều này phù hợp với ngữ nghĩa POSIX).Có thể gọi phương thức này nhiều lần cho cùng một obj: lần gọi tiếp theo sẽ cập nhật event mask của obj, hoạt động như
modify().
- unregister(obj: Any) None¶
Xóa obj khỏi tập hợp các luồng đã đăng ký. Việc hủy đăng ký một obj chưa được đăng ký hiện tại không phải là lỗi (lần gọi không có tác dụng trong trường hợp đó).
- modify(obj: Any, eventmask: int) None¶
Thay đổi event mask cho một obj đã đăng ký thành eventmask. Đưa ra
OSErrorvớierrno.ENOENTnếu obj chưa được đăng ký.
- poll(timeout: int = -1, /) List[Tuple]¶
Chặn cho đến khi ít nhất một luồng đã đăng ký sẵn sàng hoặc báo hiệu điều kiện ngoại lệ, sau đó trả về danh sách các luồng đã kích hoạt.
timeout là thời gian chờ tối đa tính bằng mili giây. Nếu bị bỏ qua hoặc là
-1, cuộc gọi sẽ chặn vô thời hạn;0trả về ngay lập tức (một lần thăm dò không chặn).Trả về danh sách các tuple
(obj, event, ...), một phần tử cho mỗi luồng đã kích hoạt.objlà luồng đã đăng ký vàeventlà phép OR theo bit của các cờselect.POLLIN/select.POLLOUT/select.POLLERR/select.POLLHUPđã xảy ra. Mỗi tuple có thể chứa thêm các phần tử được định nghĩa bởi implementation, vì vậy không nên giả định độ dài chính xác là 2. Nếu timeout hết mà không có gì sẵn sàng, một danh sách trống sẽ được trả về.select.POLLHUPvàselect.POLLERRcó thể được trả về bất kỳ lúc nào (ngay cả khi không được yêu cầu) và phải được xử lý -- thường bằng cách hủy đăng ký và đóng luồng bị ảnh hưởng -- nếu không các lần gọi tiếp theo sẽ tiếp tục trả về ngay lập tức với các cờ này được đặt cho luồng đó.Mọi hàm gọi lại đã được lên lịch đang chờ xử lý đều được đảm bảo sẽ chạy trước khi vòng lặp thăm dò được bắt đầu.
Sự khác biệt so với CPython
Các tuple trả về có thể chứa nhiều hơn 2 phần tử, như đã mô tả ở trên.
- ipoll(timeout: int = -1, flags: int = 0, /) Iterator[Tuple]¶
Tương tự như
poll(), nhưng thay vì xây dựng một danh sách, nó trả về một iterator mang lại một tuple(obj, event, ...)mỗi lần. Điều này tránh cấp phát bộ nhớ mỗi lần gọi, điều quan trọng đối với các bộ lên lịch I/O bất đồng bộ.Tuple được tạo ra là thuộc về callee: nó được tái sử dụng (ghi đè) ở lần lặp tiếp theo, vì vậy nội dung của nó phải được tiêu thụ trong thân vòng lặp và không được lưu trữ tham chiếu đến nó.
timeout có ý nghĩa tương tự như đối với
poll(). Nếu flags là1, hành vi one-shot được sử dụng: một luồng có sự kiện đã kích hoạt sẽ tự động xóa event mask của nó (tương đương vớipoll.modify(obj, 0)), vì vậy không có sự kiện nào được báo cáo thêm cho nó cho đến khi mask của nó được đặt lại bằngmodify().Mọi hàm gọi lại đã được lên lịch đang chờ xử lý đều được đảm bảo sẽ chạy trước khi vòng lặp thăm dò được bắt đầu.
Sự khác biệt so với CPython
Phương thức này là một phần mở rộng của MicroPython.