selectors
— 高階 I/O 多路複用¶
3.4 版本新增。
原始碼: Lib/selectors.py
簡介¶
此模組允許高階和高效的 I/O 多路複用,它構建於 select
模組的原語之上。除非使用者想要精確控制所使用的作業系統級原語,否則建議使用此模組代替。
它定義了一個 BaseSelector
抽象基類,以及幾個具體的實現(KqueueSelector
, EpollSelector
…),這些實現可用於等待多個檔案物件上的 I/O 就緒通知。在以下內容中,“檔案物件”是指任何具有 fileno()
方法的物件,或原始檔案描述符。參見 檔案物件。
DefaultSelector
是當前平臺上可用的最有效實現的別名:這應該是大多數使用者的預設選擇。
注意
支援的檔案物件的型別取決於平臺:在 Windows 上,支援套接字,但不支援管道,而在 Unix 上,兩者都支援(也可能支援其他型別,如 FIFO 或特殊檔案裝置)。
參見
select
低階 I/O 多路複用模組。
可用性:非 WASI。
此模組在 WebAssembly 上不起作用或不可用。有關更多資訊,請參閱 WebAssembly 平臺。
類¶
類層次結構
BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector
在以下內容中,events 是一個按位掩碼,指示應在給定檔案物件上等待哪些 I/O 事件。它可以是模組常量的組合,如下所示
- class selectors.SelectorKey¶
SelectorKey
是一個namedtuple
,用於將檔案物件與其底層檔案描述符、選定的事件掩碼和附加的資料相關聯。它由幾個BaseSelector
方法返回。- fileobj¶
已註冊的檔案物件。
- fd¶
底層檔案描述符。
- events¶
必須在此檔案物件上等待的事件。
- data¶
與此檔案物件關聯的可選不透明資料:例如,這可以用來儲存每個客戶端的會話 ID。
- class selectors.BaseSelector¶
BaseSelector
用於等待多個檔案物件上的 I/O 事件就緒。它支援檔案流的註冊、登出和一個在這些流上等待 I/O 事件的方法,並帶有可選的超時。它是一個抽象基類,因此不能例項化。請改用DefaultSelector
,或者如果希望專門使用某個實現,並且你的平臺支援,請使用SelectSelector
、KqueueSelector
等。BaseSelector
及其具體實現支援 上下文管理器 協議。- abstractmethod register(fileobj, events, data=None)¶
註冊一個檔案物件以進行選擇,監視它的 I/O 事件。
fileobj 是要監視的檔案物件。它可以是整數檔案描述符,也可以是具有
fileno()
方法的物件。events 是要監視的事件的按位掩碼。data 是一個不透明的物件。這將返回一個新的
SelectorKey
例項,或者在事件掩碼或檔案描述符無效的情況下引發ValueError
,或者在檔案物件已註冊的情況下引發KeyError
。
- abstractmethod unregister(fileobj)¶
從選擇中登出檔案物件,將其從監視中刪除。檔案物件應在關閉之前登出。
fileobj 必須是之前註冊的檔案物件。
這將返回關聯的
SelectorKey
例項,或者如果 fileobj 未註冊,則引發KeyError
。如果 fileobj 無效(例如,它沒有fileno()
方法或其fileno()
方法具有無效的返回值),它將引發ValueError
。
- modify(fileobj, events, data=None)¶
更改已註冊檔案物件的監視事件或附加資料。
這等效於
BaseSelector.unregister(fileobj)
,後跟BaseSelector.register(fileobj, events, data)
,但可以更有效地實現。這將返回一個新的
SelectorKey
例項,或者在事件掩碼或檔案描述符無效的情況下引發ValueError
,或者在檔案物件未註冊的情況下引發KeyError
。
- abstractmethod select(timeout=None)¶
等待直到一些已註冊的檔案物件準備就緒,或超時過期。
如果
timeout > 0
,則指定最大等待時間,以秒為單位。如果timeout <= 0
,則呼叫不會阻塞,並將報告當前準備就緒的檔案物件。如果 timeout 為None
,則呼叫將阻塞,直到受監視的檔案物件準備就緒。這將返回一個
(key, events)
元組列表,每個準備就緒的檔案物件一個。key 是與就緒檔案物件對應的
SelectorKey
例項。events 是該檔案物件上就緒的事件的位掩碼。注意
如果當前程序收到訊號,則此方法可以在任何檔案物件就緒或超時時間過去之前返回:在這種情況下,將返回一個空列表。
在 3.5 版本中更改: 如果訊號處理程式沒有引發異常,則選擇器現在會在被訊號中斷時使用重新計算的超時時間重試(有關基本原理,請參閱PEP 475),而不是在超時之前返回一個空事件列表。
- close()¶
關閉選擇器。
必須呼叫此方法以確保釋放所有底層資源。選擇器一旦關閉,就不得再使用。
- get_key(fileobj)¶
返回與已註冊檔案物件關聯的鍵。
這將返回與此檔案物件關聯的
SelectorKey
例項,如果該檔案物件未註冊,則引發KeyError
異常。
- abstractmethod get_map()¶
返回檔案物件到選擇器鍵的對映。
這將返回一個
Mapping
例項,該例項將已註冊的檔案物件對映到它們關聯的SelectorKey
例項。
- class selectors.DefaultSelector¶
預設的選擇器類,使用當前平臺上可用的最有效實現。這應該是大多數使用者的預設選擇。
- class selectors.SelectSelector¶
基於
select.select()
的選擇器。
- class selectors.PollSelector¶
基於
select.poll()
的選擇器。
- class selectors.EpollSelector¶
基於
select.epoll()
的選擇器。- fileno()¶
這將返回底層
select.epoll()
物件使用的檔案描述符。
- class selectors.DevpollSelector¶
基於
select.devpoll()
的選擇器。- fileno()¶
這將返回底層
select.devpoll()
物件使用的檔案描述符。
在 3.5 版本中新增。
- class selectors.KqueueSelector¶
基於
select.kqueue()
的選擇器。- fileno()¶
這將返回底層
select.kqueue()
物件使用的檔案描述符。
示例¶
這是一個簡單的回聲伺服器實現
import selectors
import socket
sel = selectors.DefaultSelector()
def accept(sock, mask):
conn, addr = sock.accept() # Should be ready
print('accepted', conn, 'from', addr)
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn, mask):
data = conn.recv(1000) # Should be ready
if data:
print('echoing', repr(data), 'to', conn)
conn.send(data) # Hope it won't block
else:
print('closing', conn)
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('localhost', 1234))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)