selectors --- 高級 I/O 復用庫?
3.4 新版功能.
源碼: Lib/selectors.py
概述?
此模塊允許高層級且高效率的 I/O 復用,它建立在 select 模塊原型的基礎之上。 推薦用戶改用此模塊,除非他們希望對所使用的 OS 層級原型進行精確控制。
它定義了一個 BaseSelector 抽象基類,以及多個實際的實現 (KqueueSelector, EpollSelector...),它們可被用于在多個文件對象上等待 I/O 就緒通知。 在下文中,"文件對象" 是指任何具有 fileno() 方法的對象,或是一個原始文件描述器。 參見 file object。
DefaultSelector 是一個指向當前平臺上可用的最高效實現的別名:這應為大多數用戶的默認選擇。
注解
受支持的文件對象類型取決于具體平臺:在 Windows 上,支持套接字但不支持管道,而在 Unix 上兩者均受支持(某些其他類型也可能受支持,例如 fifo 或特殊文件設備等)。
參見
select低層級的 I/O 多路復用模塊。
類?
類的層次結構:
BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector
下文中,events 一個位掩碼,指明哪些 I/O 事件要在給定的文件對象上執行等待。 它可以是以下模塊級常量的組合:
常數
含義
EVENT_READ可讀
EVENT_WRITE可寫
-
class
selectors.SelectorKey? SelectorKey是一個namedtuple,用來將文件對象關聯到其下層的文件描述器、選定事件掩碼和附加數據等。 它會被某些BaseSelector方法返回。-
fileobj? 已注冊的文件對象。
-
fd? 下層的文件描述器。
-
events? 必須在此文件對象上被等待的事件。
-
data? 可選的關聯到此文件對象的不透明數據:例如,這可被用來存儲各個客戶端的會話 ID。
-
-
class
selectors.BaseSelector? 一個
BaseSelector,用來在多個文件對象上等待 I/O 事件就緒。 它支持文件流注冊、注銷,以及在這些流上等待 I/O 事件的方法。 它是一個抽象基類,因此不能被實例化。 請改用DefaultSelector,或者SelectSelector,KqueueSelector等。 如果你想要指明使用某個實現,并且你的平臺支持它的話。BaseSelector及其具體實現支持 context manager 協議。-
abstractmethod
register(fileobj, events, data=None)? 注冊一個用于選擇的文件對象,在其上監視 I/O 事件。
fileobj 是要監視的文件對象。 它可以是整數形式的文件描述符或者具有
fileno()方法的對象。 events 是要監視的事件的位掩碼。 data 是一個不透明對象。這將返回一個新的
SelectorKey實例,或在出現無效事件掩碼或文件描述符時引發ValueError,或在文件對象已被注冊時引發KeyError。
-
abstractmethod
unregister(fileobj)? 注銷對一個文件對象的選擇,移除對它的監視。 在文件對象被關閉之前應當先將其注銷。
fileobj 必須是之前已注冊的文件對象。
這將返回已關聯的
SelectorKey實例,或者如果 fileobj 未注冊則會引發KeyError。 It will raiseValueError如果 fileobj 無效(例如它沒有fileno()方法或其fileno()方法返回無效值)。
-
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()? 返回從文件對象到選擇器鍵的映射。
這將返回一個將已注冊文件對象映射到與其相關聯的
SelectorKey實例的Mapping實例。
-
abstractmethod
-
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)
