該模塊提供了對 select() 和 poll() 函數的訪問,這些函數在大多數操作系統中是可用的。在 Solaris 及其衍生版本上可用 devpoll(),在 Linux 2.5+ 上可用 epoll(),在大多數 BSD 上可用 kqueue()。注意,在 Windows 上,本模塊僅適用於套接字;在其他操作系統上,本模塊也適用於其他文件類型(特別地,在 Unix 上也適用於管道)。本模塊不能用於常規文件,不能檢測出(自上次讀取文件後)文件是否有新數據寫入。
- select.devpoll()
(僅支持 Solaris 及其衍生版本)返回一個 /dev/poll 輪詢對象,請參閱下方 /dev/poll 輪詢對象 獲取 devpoll 對象所支持的方法。
devpoll() 對象與實例化時允許的文件描述符數量有關,如果在程序中降低了此數值,devpoll() 調用將失敗。如果程序提高了此數值,devpoll() 可能會返回一個不完整的活動文件描述符列表。
- select.epoll(sizehint=-1, flags=0)
(僅支持 Linux 2.5.44 或更高版本)返回一個輪詢對象,該對象可作爲 I/O 事件的邊緣觸發或水平觸發接口。
sizehint 指示 epoll 預計需要註冊的事件數。它必須爲正數,或爲 -1 以使用默認值。它僅在 epoll_create1() 不可用的舊系統上有用,其他情況下它沒有任何作用(儘管仍會檢查其值)。
flags 已經棄用且完全被忽略。但是,如果提供該值,則它必須是 0 或 select.EPOLL_CLOEXEC,否則會拋出 OSError 異常。
請參閱下方 邊緣觸發和水平觸發的輪詢 (epoll) 對象 獲取 epoll 對象所支持的方法。
epoll 對象支持上下文管理器:當在 with 語句中使用時,新建的文件描述符會在運行至語句塊結束時自動銷燬。
- select.poll()
(部分操作系統不支持)返回一個輪詢對象,該對象支持註冊和註銷文件描述符,支持對描述符進行輪詢以獲取 I/O 事件。有關輪詢對象支持的方法,請參閱下方 Poll 對象 部分。
- select.kqueue()
(僅支持 BSD)返回一個內核隊列對象,請參閱下方 Kqueue 對象 獲取 kqueue 對象所支持的方法。
- 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:等待“異常情況”(請參閱當前系統的手冊,以獲取哪些情況稱爲異常情況)
- select.PIPE_BUF
當一個管道已經被 select() 、 poll() 或本模塊中的某個接口報告爲可寫入時,可以在不阻塞該管道的情況下寫入的最小字節數。它不適用於套接字等其他類型的文件類對象。
/dev/poll 輪詢對象
Solaris 及其衍生版本具備 /dev/poll。select() 複雜度爲 O(最高文件描述符),poll() 爲 O(文件描述符數量),而 /dev/poll 爲 O(活動的文件描述符)。
/dev/poll 的行爲與標準 poll() 對象十分類似。
- devpoll.close()
關閉輪詢對象的文件描述符。
3.4 新版功能.
- devpoll.closed
如果輪詢對象已關閉,則返回 True。
- devpoll.fileno()
返回輪詢對象的文件描述符對應的數字。
- devpoll.register(fd[, eventmask])
在輪詢對象中註冊文件描述符。這樣,將來調用 poll() 方法時將檢查文件描述符是否有未處理的 I/O 事件。fd 可以是整數,也可以是帶有 fileno() 方法的對象(該方法返回一個整數)。文件對象已經實現了 fileno(),因此它們也可以用作參數。
eventmask 是可選的位掩碼,用於指定要檢查的事件類型。這些常量與 poll() 對象所用的相同。本參數的默認值是常量 POLLIN、POLLPRI 和 POLLOUT 的組合。
- devpoll.modify(fd[, eventmask])
此方法先執行 unregister() 後執行 register() 。直接執行此操作效率(稍微)高一些。
- devpoll.unregister(fd)
刪除輪詢對象正在跟蹤的某個文件描述符。與 register() 方法類似,fd 可以是整數,也可以是帶有 fileno() 方法的對象(該方法返回一個整數)。
嘗試刪除從未註冊過的文件描述符將被安全地忽略。
- devpoll.poll([timeout])
輪詢已註冊的文件描述符的集合,並返回一個列表,列表可能爲空,也可能有多個 (fd, event) 二元組,其中包含了要報告事件或錯誤的描述符。fd 是文件描述符,event 是一個位掩碼,表示該描述符所報告的事件 — POLLIN 表示可以讀取,POLLOUT 表示該描述符可以寫入,依此類推。空列表表示調用超時,沒有任何文件描述符報告事件。如果指定了 timeout,它將指定系統等待事件時,等待多長時間後返回(以毫秒爲單位)。如果 timeout 爲空,-1 或 None,則本調用將阻塞,直到輪詢對象發生事件爲止。
邊緣觸發和水平觸發的輪詢 (epoll) 對象
http://linux.die.net/man/4/epoll
屏蔽事件
常數
含義
EPOLLIN
可讀
EPOLLOUT
可寫
EPOLLPRI
緊急數據讀取
EPOLLERR
在關聯的文件描述符上有錯誤情況發生
EPOLLHUP
關聯的文件描述符已掛起
EPOLLET
設置觸發方式爲邊緣觸發,默認爲水平觸發
EPOLLONESHOT
設置 one-shot 模式。觸發一次事件後,該描述符會在輪詢對象內部被禁用。
EPOLLEXCLUSIVE
當已關聯的描述符發生事件時,僅喚醒一個 epoll 對象。默認(如果未設置此標誌)是喚醒所有輪詢該描述符的 epoll 對象。
EPOLLRDHUP
流套接字的對側關閉了連接或關閉了寫入到一半的連接。
EPOLLRDNORM
Equivalent to EPOLLIN
EPOLLRDBAND
可以讀取優先數據帶。
EPOLLWRNORM
Equivalent to EPOLLOUT
EPOLLWRBAND
可以寫入優先級數據。
EPOLLMSG
忽略
epoll.close()
關閉用於控制 epoll 對象的那個文件描述符。
epoll.closed
如果 epoll 對象已關閉,則返回 True。
epoll.fileno()
返回用於控制 epoll 對象的文件描述符對應的數字。
epoll.fromfd(fd)
根據給定的文件描述符創建 epoll 對象。
epoll.register(fd[, eventmask])
在 epoll 對象中註冊一個文件描述符。
epoll.modify(fd, eventmask)
修改一個已註冊的文件描述符。
epoll.unregister(fd)
從 epoll 對象中刪除一個已註冊的文件描述符。
epoll.poll(timeout=-1, maxevents=-1)
等待事件發生,timeout 是浮點數,單位爲秒。
Poll 對象
大多數 Unix 系統支持 poll() 系統調用,爲服務器提供了更好的可伸縮性,使服務器可以同時服務於大量客戶端。poll() 的伸縮性更好,因爲該調用內部僅列出所關注的文件描述符,而 select() 會構造一個 bitmap,在其中將所關注的描述符所對應的 bit 打開,然後重新遍歷整個 bitmap。因此 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)
修改一個已註冊的文件描述符,等同於 register(fd, eventmask)。嘗試修改未註冊的文件描述符會拋出 OSError 異常,錯誤碼爲 ENOENT。
poll.unregister(fd)
刪除輪詢對象正在跟蹤的某個文件描述符。與 register() 方法類似,fd 可以是整數,也可以是帶有 fileno() 方法的對象(該方法返回一個整數)。
嘗試刪除從未註冊過的文件描述符會拋出 KeyError 異常。
poll.poll([timeout])
輪詢已註冊的文件描述符的集合,並返回一個列表,列表可能爲空,也可能有多個 (fd, event) 二元組,其中包含了要報告事件或錯誤的描述符。fd 是文件描述符,event 是一個位掩碼,表示該描述符所報告的事件 — POLLIN 表示可以讀取,POLLOUT 表示該描述符可以寫入,依此類推。空列表表示調用超時,沒有任何文件描述符報告事件。如果指定了 timeout,它將指定系統等待事件時,等待多長時間後返回(以毫秒爲單位)。如果 timeout 爲空、負數 或 None,則本調用將阻塞,直到輪詢對象發生事件爲止。
Kqueue 對象
kqueue.close()
關閉用於控制 kqueue 對象的文件描述符。
kqueue.closed
如果 kqueue 對象已關閉,則返回 True。
kqueue.fileno()
返回用於控制 epoll 對象的文件描述符對應的數字。
kqueue.fromfd(fd)
根據給定的文件描述符創建 kqueue 對象。
kqueue.control(changelist, max_events[, timeout=None]) → eventlist
Kevent 的低級接口
-
changelist must be an iterable of kevent object or None
-
max_events 必須是 0 或一個正整數。
-
timeout in seconds (floats possible)
Kevent 對象
https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2
kevent.ident
用於區分事件的標識值。其解釋取決於篩選器,但該值通常是文件描述符。在構造函數中,該標識值可以是整數或帶有 fileno() 方法的對象。kevent 在內部存儲整數。
kevent.filter
內核過濾器的名稱。
常數 |
含義 |
KQ_FILTER_READ |
獲取描述符,並在有數據可讀時返回 |
KQ_FILTER_WRITE |
獲取描述符,並在有數據可寫時返回 |
KQ_FILTER_AIO |
AIO 請求 |
KQ_FILTER_VNODE |
當在 fflag 中監視的一個或多個請求事件發生時返回 |
KQ_FILTER_PROC |
監視進程ID上的事件 |
KQ_FILTER_NETDEV |
觀察網絡設備上的事件[在Mac OS X上不可用] |
KQ_FILTER_SIGNAL |
每當監視的信號傳遞到進程時返回 |
KQ_FILTER_TIMER |
建立一個任意的計時器 |
kevent.flags
篩選器操作。
常數 |
含義 |
KQ_EV_ADD |
添加或修改事件 |
KQ_EV_DELETE |
從隊列中刪除事件 |
KQ_EV_ENABLE |
Permitscontrol() 返回事件 |
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 filter flags:
常數 |
含義 |
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 過濾器標誌(在Mac OS X上不可用):
常數 |
含義 |
KQ_NOTE_LINKUP |
鏈接已建立 |
KQ_NOTE_LINKDOWN |
鏈接已斷開 |
KQ_NOTE_LINKINV |
鏈接狀態無效 |
kevent.data
過濾特定數據。
kevent.udata
用戶定義的值。