selectors --- 高級(jí) I/O 復(fù)用庫(kù)?

3.4 新版功能.

源碼: Lib/selectors.py


概述?

此模塊允許高層級(jí)且高效率的 I/O 復(fù)用,它建立在 select 模塊原型的基礎(chǔ)之上。 推薦用戶改用此模塊,除非他們希望對(duì)所使用的 OS 層級(jí)原型進(jìn)行精確控制。

它定義了一個(gè) BaseSelector 抽象基類,以及多個(gè)實(shí)際的實(shí)現(xiàn) (KqueueSelector, EpollSelector...),它們可被用于在多個(gè)文件對(duì)象上等待 I/O 就緒通知。 在下文中,"文件對(duì)象" 是指任何具有 fileno() 方法的對(duì)象,或是一個(gè)原始文件描述符。 參見 file object。

DefaultSelector 是一個(gè)指向當(dāng)前平臺(tái)上可用的最高效實(shí)現(xiàn)的別名:這應(yīng)為大多數(shù)用戶的默認(rèn)選擇。

備注

受支持的文件對(duì)象類型取決于具體平臺(tái):在 Windows 上,支持套接字但不支持管道,而在 Unix 上兩者均受支持(某些其他類型也可能受支持,例如 fifo 或特殊文件設(shè)備等)。

參見

select

低層級(jí)的 I/O 多路復(fù)用模塊。

?

類的層次結(jié)構(gòu):

BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector

下文中,events 一個(gè)位掩碼,指明哪些 I/O 事件要在給定的文件對(duì)象上執(zhí)行等待。 它可以是以下模塊級(jí)常量的組合:

常量

含意

EVENT_READ

可讀

EVENT_WRITE

可寫

class selectors.SelectorKey?

SelectorKey 是一個(gè) namedtuple,用來(lái)將文件對(duì)象關(guān)聯(lián)到其下層的文件描述符、選定事件掩碼和附加數(shù)據(jù)等。 它會(huì)被某些 BaseSelector 方法返回。

fileobj?

已注冊(cè)的文件對(duì)象。

fd?

下層的文件描述符。

events?

必須在此文件對(duì)象上被等待的事件。

data?

可選的關(guān)聯(lián)到此文件對(duì)象的不透明數(shù)據(jù):例如,這可被用來(lái)存儲(chǔ)各個(gè)客戶端的會(huì)話 ID。

class selectors.BaseSelector?

一個(gè) BaseSelector,用來(lái)在多個(gè)文件對(duì)象上等待 I/O 事件就緒。 它支持文件流注冊(cè)、注銷,以及在這些流上等待 I/O 事件的方法。 它是一個(gè)抽象基類,因此不能被實(shí)例化。 請(qǐng)改用 DefaultSelector,或者 SelectSelector, KqueueSelector 等。 如果你想要指明使用某個(gè)實(shí)現(xiàn),并且你的平臺(tái)支持它的話。 BaseSelector 及其具體實(shí)現(xiàn)支持 context manager 協(xié)議。

abstractmethod register(fileobj, events, data=None)?

注冊(cè)一個(gè)用于選擇的文件對(duì)象,在其上監(jiān)視 I/O 事件。

fileobj 是要監(jiān)視的文件對(duì)象。 它可以是整數(shù)形式的文件描述符或者具有 fileno() 方法的對(duì)象。 events 是要監(jiān)視的事件的位掩碼。 data 是一個(gè)不透明對(duì)象。

這將返回一個(gè)新的 SelectorKey 實(shí)例,或在出現(xiàn)無(wú)效事件掩碼或文件描述符時(shí)引發(fā) ValueError,或在文件對(duì)象已被注冊(cè)時(shí)引發(fā) KeyError

abstractmethod unregister(fileobj)?

注銷對(duì)一個(gè)文件對(duì)象的選擇,移除對(duì)它的監(jiān)視。 在文件對(duì)象被關(guān)閉之前應(yīng)當(dāng)先將其注銷。

fileobj 必須是之前已注冊(cè)的文件對(duì)象。

這將返回已關(guān)聯(lián)的 SelectorKey 實(shí)例,或者如果 fileobj 未注冊(cè)則會(huì)引發(fā) KeyError。 It will raise ValueError 如果 fileobj 無(wú)效(例如它沒有 fileno() 方法或其 fileno() 方法返回?zé)o效值)。

modify(fileobj, events, data=None)?

更改已注冊(cè)文件對(duì)象所監(jiān)視的事件或所附帶的數(shù)據(jù)。

這等價(jià)于 BaseSelector.unregister(fileobj)()BaseSelector.register(fileobj, events, data)(),區(qū)別在于它可以被更高效地實(shí)現(xiàn)。

這將返回一個(gè)新的 SelectorKey 實(shí)例,或在出現(xiàn)無(wú)效事件掩碼或文件描述符時(shí)引發(fā) ValueError,或在文件對(duì)象未被注冊(cè)時(shí)引發(fā) KeyError。

abstractmethod select(timeout=None)?

等待直到有已注冊(cè)的文件對(duì)象就緒,或是超過(guò)時(shí)限。

如果 timeout > 0,這指定以秒數(shù)表示的最大等待時(shí)間。 如果 timeout <= 0,調(diào)用將不會(huì)阻塞,并將報(bào)告當(dāng)前就緒的文件對(duì)象。 如果 timeoutNone,調(diào)用將阻塞直到某個(gè)被監(jiān)視的文件對(duì)象就緒。

這將返回由 (key, events) 元組構(gòu)成的列表,每項(xiàng)各表示一個(gè)就緒的文件對(duì)象。

key 是對(duì)應(yīng)于就緒文件對(duì)象的 SelectorKey 實(shí)例。 events 是在此文件對(duì)象上等待的事件位掩碼。

備注

如果當(dāng)前進(jìn)程收到一個(gè)信號(hào),此方法可在任何文件對(duì)象就緒之前或超出時(shí)限時(shí)返回:在此情況下,將返回一個(gè)空列表。

在 3.5 版更改: 現(xiàn)在當(dāng)被某個(gè)信號(hào)中斷時(shí),如果信號(hào)處理程序沒有引發(fā)異常,選擇器會(huì)用重新計(jì)算的超時(shí)值進(jìn)行重試(請(qǐng)查看 PEP 475 其理由),而不是在超時(shí)之前返回空的事件列表。

close()?

關(guān)閉選擇器。

必須調(diào)用這個(gè)方法以確保下層資源會(huì)被釋放。 選擇器被關(guān)閉后將不可再使用。

get_key(fileobj)?

返回關(guān)聯(lián)到某個(gè)已注冊(cè)文件對(duì)象的鍵。

此方法將返回關(guān)聯(lián)到文件對(duì)象的 SelectorKey 實(shí)例,或在文件對(duì)象未注冊(cè)時(shí)引發(fā) KeyError。

abstractmethod get_map()?

返回從文件對(duì)象到選擇器鍵的映射。

這將返回一個(gè)將已注冊(cè)文件對(duì)象映射到與其相關(guān)聯(lián)的 SelectorKey 實(shí)例的 Mapping 實(shí)例。

class selectors.DefaultSelector?

默認(rèn)的選擇器類,使用當(dāng)前平臺(tái)上可用的最高效實(shí)現(xiàn)。 這應(yīng)為大多數(shù)用戶的默認(rèn)選擇。

class selectors.SelectSelector?

基于 select.select() 的選擇器。

class selectors.PollSelector?

基于 select.poll() 的選擇器。

class selectors.EpollSelector?

基于 select.epoll() 的選擇器。

fileno()?

此方法將返回由下層 select.epoll() 對(duì)象所使用的文件描述符。

class selectors.DevpollSelector?

基于 select.devpoll() 的選擇器。

fileno()?

此方法將返回由下層 select.devpoll() 對(duì)象所使用的文件描述符。

3.5 新版功能.

class selectors.KqueueSelector?

基于 select.kqueue() 的選擇器。

fileno()?

此方法將返回由下層 select.kqueue() 對(duì)象所使用的文件描述符。

例子?

下面是一個(gè)簡(jiǎn)單的回顯服務(wù)器實(shí)現(xiàn):

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)