python3從零學習-5.8.2、select — Waiting for I/O 完成

該模塊提供了對 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

用戶定義的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章