select
— 等待 I/O 完成¶
此模組提供了對大多數作業系統中可用的 select()
和 poll()
函式、Solaris 及其衍生產品上可用的 devpoll()
、Linux 2.5+ 上可用的 epoll()
和大多數 BSD 上可用的 kqueue()
函式的訪問。請注意,在 Windows 上,它僅適用於套接字;在其他作業系統上,它也適用於其他檔案型別(特別是在 Unix 上,它適用於管道)。它不能用於常規檔案來確定檔案自上次讀取以來是否已增長。
可用性:非 WASI。
此模組在 WebAssembly 上不起作用或不可用。有關更多資訊,請參閱 WebAssembly 平臺。
該模組定義了以下內容
- select.devpoll()¶
(僅在 Solaris 及其衍生產品上受支援。)返回一個
/dev/poll
輪詢物件;有關 devpoll 物件支援的方法,請參閱下面的 /dev/poll 輪詢物件 部分。devpoll()
物件與例項化時允許的檔案描述符數量相關聯。如果您的程式減少此值,devpoll()
將失敗。如果您的程式增加此值,devpoll()
可能會返回不完整的活動檔案描述符列表。新的檔案描述符是不可繼承的。
在 3.3 版本加入。
3.4 版本發生變更: 新的檔案描述符現在是不可繼承的。
- select.epoll(sizehint=-1, flags=0)¶
(僅在 Linux 2.5.44 及更高版本上受支援。)返回一個邊緣輪詢物件,該物件可用作 I/O 事件的邊緣或水平觸發介面。
sizehint 通知 epoll 預期的註冊事件數量。它必須是正數,或者
-1
以使用預設值。它僅在不支援epoll_create1()
的舊系統上使用;否則它沒有效果(儘管其值仍會被檢查)。flags 已被棄用並完全忽略。但是,如果提供,其值必須為
0
或select.EPOLL_CLOEXEC
,否則會引發OSError
。有關 epolling 物件支援的方法,請參閱下面的 邊緣和水平觸發輪詢 (epoll) 物件 部分。
epoll
物件支援上下文管理協議:當在with
語句中使用時,新的檔案描述符會在塊結束時自動關閉。新的檔案描述符是不可繼承的。
3.3 版本發生變更: 添加了 flags 引數。
3.4 版本發生變更: 添加了對
with
語句的支援。新的檔案描述符現在是不可繼承的。自 3.4 版本起已棄用: flags 引數。現在預設使用
select.EPOLL_CLOEXEC
。使用os.set_inheritable()
使檔案描述符可繼承。
- select.kqueue()¶
(僅在 BSD 上受支援。)返回一個核心佇列物件;有關 kqueue 物件支援的方法,請參閱下面的 Kqueue 物件 部分。
新的檔案描述符是不可繼承的。
3.4 版本發生變更: 新的檔案描述符現在是不可繼承的。
- select.kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)¶
(僅在 BSD 上受支援。)返回一個核心事件物件;有關 kevent 物件支援的方法,請參閱下面的 Kevent 物件 部分。
- select.select(rlist, wlist, xlist[, timeout])¶
這是一個直接的 Unix
select()
系統呼叫介面。前三個引數是“可等待物件”的可迭代物件:可以是表示檔案描述符的整數,也可以是具有名為fileno()
的無引數方法並返回此類整數的物件rlist: 等待直到可讀
wlist: 等待直到可寫
xlist: 等待“異常情況”(請參閱手冊頁,瞭解您的系統認為什麼是此類情況)
允許空的可迭代物件,但接受三個空的可迭代物件是平臺相關的。(已知在 Unix 上有效,但在 Windows 上無效。)可選的 timeout 引數指定以秒為單位的浮點數超時時間。當省略 timeout 引數時,函式會阻塞,直到至少有一個檔案描述符準備就緒。超時值為零表示輪詢,永不阻塞。
返回值是一個包含就緒物件的列表元組:前三個引數的子集。當達到超時時間而沒有檔案描述符就緒時,返回三個空列表。
可迭代物件中可接受的物件型別包括 Python 檔案物件(例如
sys.stdin
,或由open()
或os.popen()
返回的物件),由socket.socket()
返回的套接字物件。您也可以自己定義一個 包裝器 類,只要它有一個合適的fileno()
方法(該方法確實返回一個檔案描述符,而不僅僅是一個隨機整數)。備註
Windows 上的檔案物件不可接受,但套接字可以。在 Windows 上,底層的
select()
函式由 WinSock 庫提供,不處理非源自 WinSock 的檔案描述符。3.5 版本發生變更: 當被訊號中斷時,函式現在會使用重新計算的超時時間重試,除非訊號處理程式引發異常(請參閱 PEP 475 以瞭解其原理),而不是引發
InterruptedError
。
- select.PIPE_BUF¶
當管道被
select()
、poll()
或此模組中的其他介面報告為可寫時,可以無阻塞地寫入管道的最小位元組數。這不適用於其他型別的檔案類物件,例如套接字。POSIX 保證此值至少為 512。
可用性: Unix
在 3.2 版本加入。
/dev/poll
輪詢物件¶
Solaris 及其衍生產品具有 /dev/poll
。雖然 select()
是 O(最高檔案描述符),poll()
是 O(檔案描述符數量),但 /dev/poll
是 O(活動檔案描述符)。
/dev/poll
的行為與標準 poll()
物件非常接近。
- devpoll.close()¶
關閉輪詢物件的檔案描述符。
在 3.4 版本加入。
- devpoll.closed¶
如果輪詢物件已關閉,則為
True
。在 3.4 版本加入。
- devpoll.fileno()¶
返回輪詢物件的檔案描述符編號。
在 3.4 版本加入。
- devpoll.register(fd[, eventmask])¶
向輪詢物件註冊一個檔案描述符。未來的
poll()
方法呼叫將檢查檔案描述符是否有任何待處理的 I/O 事件。fd 可以是整數,也可以是具有返回整數的fileno()
方法的物件。檔案物件實現了fileno()
,因此它們也可以用作引數。eventmask 是一個可選的位掩碼,描述您要檢查的事件型別。常量與
poll()
物件相同。預設值是常量POLLIN
、POLLPRI
和POLLOUT
的組合。警告
註冊一個已註冊的檔案描述符不是錯誤,但結果未定義。適當的操作是先登出或修改它。這是與
poll()
相比的一個重要區別。
- devpoll.modify(fd[, eventmask])¶
此方法執行
unregister()
,然後執行register()
。它比顯式執行相同的操作效率更高(一點點)。
- devpoll.unregister(fd)¶
從輪詢物件中移除正在跟蹤的檔案描述符。與
register()
方法一樣,fd 可以是整數,也可以是具有返回整數的fileno()
方法的物件。嘗試移除從未註冊的檔案描述符會被安全地忽略。
- devpoll.poll([timeout])¶
輪詢一組已註冊的檔案描述符,並返回一個可能為空的列表,其中包含具有事件或錯誤的描述符的
(fd, event)
2 元組。fd 是檔案描述符,event 是一個位掩碼,其中位設定為該描述符報告的事件 —POLLIN
表示等待輸入,POLLOUT
表示描述符可寫入,依此類推。空列表表示呼叫超時,沒有檔案描述符有任何事件要報告。如果給出 timeout,它指定系統在返回之前等待事件的毫秒數。如果省略 timeout、為 -1 或None
,則呼叫將阻塞,直到此輪詢物件有事件發生。3.5 版本發生變更: 當被訊號中斷時,函式現在會使用重新計算的超時時間重試,除非訊號處理程式引發異常(請參閱 PEP 475 以瞭解其原理),而不是引發
InterruptedError
。
邊緣和水平觸發輪詢 (epoll) 物件¶
https://linux.die.net/man/4/epoll
eventmask
常量
含義
EPOLLIN
可讀
EPOLLOUT
可寫
EPOLLPRI
有緊急資料可讀
EPOLLERR
關聯檔案描述符上發生錯誤情況
EPOLLHUP
關聯檔案描述符上發生掛起
EPOLLET
設定邊緣觸發行為,預設為水平觸發行為
EPOLLONESHOT
設定單次行為。在拉出一個事件後,fd 在內部被停用
EPOLLEXCLUSIVE
當關聯的 fd 有事件時,只喚醒一個 epoll 物件。預設(如果未設定此標誌)是喚醒所有輪詢 fd 的 epoll 物件。
EPOLLRDHUP
流套接字對端關閉連線或關閉連線的寫入半部分。
EPOLLRDNORM
等同於
EPOLLIN
EPOLLRDBAND
優先順序資料帶可讀。
EPOLLWRNORM
等同於
EPOLLOUT
EPOLLWRBAND
優先順序資料可寫入。
EPOLLMSG
忽略。
EPOLLWAKEUP
防止在事件等待期間休眠。
3.6 版本新增: 添加了
EPOLLEXCLUSIVE
。它僅受 Linux 核心 4.5 或更高版本支援。3.14 版本新增: 添加了
EPOLLWAKEUP
。它僅受 Linux 核心 3.5 或更高版本支援。
- epoll.close()¶
關閉 epoll 物件的控制檔案描述符。
- epoll.closed¶
如果 epoll 物件已關閉,則為
True
。
- epoll.fileno()¶
返回控制檔案描述符的檔案描述符編號。
- epoll.fromfd(fd)¶
從給定的檔案描述符建立 epoll 物件。
- epoll.register(fd[, eventmask])¶
向 epoll 物件註冊一個 fd 描述符。
- epoll.modify(fd, eventmask)¶
修改已註冊的檔案描述符。
- epoll.poll(timeout=None, maxevents=-1)¶
等待事件。超時時間以秒為單位(浮點數)。
3.5 版本發生變更: 當被訊號中斷時,函式現在會使用重新計算的超時時間重試,除非訊號處理程式引發異常(請參閱 PEP 475 以瞭解其原理),而不是引發
InterruptedError
。
輪詢物件¶
在大多數 Unix 系統上受支援的 poll()
系統呼叫為同時服務大量客戶端的網路伺服器提供了更好的可伸縮性。poll()
具有更好的可伸縮性,因為系統呼叫只需要列出感興趣的檔案描述符,而 select()
構建一個位圖,為感興趣的 fd 開啟位,然後必須再次線性掃描整個點陣圖。select()
是 O(最高檔案描述符),而 poll()
是 O(檔案描述符數量)。
- poll.register(fd[, eventmask])¶
向輪詢物件註冊一個檔案描述符。未來的
poll()
方法呼叫將檢查檔案描述符是否有任何待處理的 I/O 事件。fd 可以是整數,也可以是具有返回整數的fileno()
方法的物件。檔案物件實現了fileno()
,因此它們也可以用作引數。eventmask 是一個可選的位掩碼,描述您要檢查的事件型別,可以是下表中描述的常量
POLLIN
、POLLPRI
和POLLOUT
的組合。如果未指定,將使用預設值檢查所有 3 種類型的事件。常量
含義
POLLIN
有資料可讀
POLLPRI
有緊急資料可讀
POLLOUT
準備輸出:寫入不會阻塞
POLLERR
某種錯誤情況
POLLHUP
掛起
POLLRDHUP
流套接字對端關閉連線,或關閉連線的寫入半部分
POLLNVAL
無效請求:描述符未開啟
註冊已註冊的檔案描述符不是錯誤,並且與僅註冊一次描述符具有相同的效果。
- poll.modify(fd, eventmask)¶
修改已註冊的 fd。這與
register(fd, eventmask)
具有相同的效果。嘗試修改從未註冊的檔案描述符會引發帶有 errnoENOENT
的OSError
異常。
- poll.unregister(fd)¶
從輪詢物件中移除正在跟蹤的檔案描述符。與
register()
方法一樣,fd 可以是整數,也可以是具有返回整數的fileno()
方法的物件。嘗試移除從未註冊的檔案描述符會導致引發
KeyError
異常。
- poll.poll([timeout])¶
輪詢一組已註冊的檔案描述符,並返回一個可能為空的列表,其中包含具有事件或錯誤的描述符的
(fd, event)
2 元組。fd 是檔案描述符,event 是一個位掩碼,其中位設定為該描述符報告的事件 —POLLIN
表示等待輸入,POLLOUT
表示描述符可寫入,依此類推。空列表表示呼叫超時,沒有檔案描述符有任何事件要報告。如果給出 timeout,它指定系統在返回之前等待事件的毫秒數。如果省略 timeout、為負數或None
,則呼叫將阻塞,直到此輪詢物件有事件發生。3.5 版本發生變更: 當被訊號中斷時,函式現在會使用重新計算的超時時間重試,除非訊號處理程式引發異常(請參閱 PEP 475 以瞭解其原理),而不是引發
InterruptedError
。
Kqueue 物件¶
- kqueue.close()¶
關閉 kqueue 物件的控制檔案描述符。
- kqueue.closed¶
如果 kqueue 物件已關閉,則為
True
。
- kqueue.fileno()¶
返回控制檔案描述符的檔案描述符編號。
- kqueue.fromfd(fd)¶
從給定的檔案描述符建立 kqueue 物件。
- kqueue.control(changelist, max_events[, timeout]) eventlist ¶
kevent 的低階介面
changelist 必須是 kevent 物件的可迭代物件或
None
max_events 必須是 0 或正整數
超時時間以秒為單位(可能為浮點數);預設值為
None
,表示永遠等待
3.5 版本發生變更: 當被訊號中斷時,函式現在會使用重新計算的超時時間重試,除非訊號處理程式引發異常(請參閱 PEP 475 以瞭解其原理),而不是引發
InterruptedError
。
Kevent 物件¶
https://man.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
- kevent.filter¶
核心過濾器的名稱。
常量
含義
KQ_FILTER_READ
接收描述符並在有資料可讀時返回
KQ_FILTER_WRITE
接收描述符並在有資料可寫時返回
KQ_FILTER_AIO
AIO 請求
KQ_FILTER_VNODE
當 fflag 中請求的一個或多個事件發生時返回
KQ_FILTER_PROC
監視程序 ID 上的事件
KQ_FILTER_NETDEV
監視網路裝置上的事件 [在 macOS 上不可用]
KQ_FILTER_SIGNAL
每當監視的訊號傳遞到程序時返回
KQ_FILTER_TIMER
建立任意定時器
- kevent.flags¶
過濾動作。
常量
含義
KQ_EV_ADD
新增或修改事件
KQ_EV_DELETE
從佇列中移除事件
KQ_EV_ENABLE
允許control()返回事件
KQ_EV_DISABLE
停用事件
KQ_EV_ONESHOT
首次發生後移除事件
KQ_EV_CLEAR
檢索事件後重置狀態
KQ_EV_SYSFLAGS
內部事件
KQ_EV_FLAG1
內部事件
KQ_EV_EOF
過濾器特定的 EOF 條件
KQ_EV_ERROR
參見返回值
- kevent.fflags¶
過濾器特定標誌。
KQ_FILTER_READ
和KQ_FILTER_WRITE
過濾器標誌常量
含義
KQ_NOTE_LOWAT
套接字緩衝區的低水位標記
KQ_FILTER_VNODE
過濾器標誌常量
含義
KQ_NOTE_DELETE
呼叫了 unlink()
KQ_NOTE_WRITE
發生寫入
KQ_NOTE_EXTEND
檔案已擴充套件
KQ_NOTE_ATTRIB
屬性已更改
KQ_NOTE_LINK
連結計數已更改
KQ_NOTE_RENAME
檔案已重新命名
KQ_NOTE_REVOKE
檔案訪問被撤銷
KQ_FILTER_PROC
過濾器標誌常量
含義
KQ_NOTE_EXIT
程序已退出
KQ_NOTE_FORK
程序已呼叫 fork()
KQ_NOTE_EXEC
程序已執行新程序
KQ_NOTE_PCTRLMASK
內部過濾器標誌
KQ_NOTE_PDATAMASK
內部過濾器標誌
KQ_NOTE_TRACK
在 fork() 之後跟蹤程序
KQ_NOTE_CHILD
在子程序上返回 NOTE_TRACK
KQ_NOTE_TRACKERR
無法附加到子程序
KQ_FILTER_NETDEV
過濾器標誌(在 macOS 上不可用)常量
含義
KQ_NOTE_LINKUP
連結已啟動
KQ_NOTE_LINKDOWN
連結已關閉
KQ_NOTE_LINKINV
連結狀態無效
- kevent.data¶
過濾器特定資料。
- kevent.udata¶
使用者定義值。