Python - selectors 模塊


selectors 模塊

它的功能與 linux 的 epoll,還是 select 模塊,  poll 等類似;

實現高效的 I/O multiplexing ,  常用於非阻塞的 socket  的編程中

官方文檔

這里

內部類

▤ BaseSelector 

  ▧ SelectSelector

  ▧ PollSelector

  ▧ EpollSelector

  ▧ DevpollSelector

  ▧ KqueueSelector

▤ DefaultSelector

  實際使用為此類, 自動選擇為當前環境中最有效的  Selector ,

  所以平時用  DefaultSelector  類就可以了,其它用不着

定義事件類型

▤ EVENT_READ  -  表示可讀

▤ EVENT_WRITE -  表示可寫

SelectorKey類

模塊定義了一個  SelectorKey 類, 一般用這個類的實例 來描述一個已經注冊的文件對象的狀態, 這個類的幾個屬性常用到:

▤ fileobj   -  表示已經注冊的文件對象;

▤ fd         -  表示文件對象的描述符,是一個整數,它是文件對象的  fileno() 方法的返回值;

▤ events -   表示注冊一個文件對象時,我們等待的 events , 即上面的 event   Mask , 是可讀呢還是可寫呢!!

▤ data    -   表示注冊一個文件對象是邦定的 data ;

常用方法

register(fileobj, events, data=None)

作用

  注冊一個文件對象。                                                     

參數

   fileobj 即可以是fd 也可以是一個擁有 fileno() 方法的對象;

   events上面的 event Mask  常量 data 

返回值

  一個 SelectorKey 類的實例

unregister(fileobj)

作用

   注銷一個已經注冊過的文件對象;      

返回值

  一個 SelectorKey 類的實例

modify(fileobj, events, data=None)

作用

  用於修改一個注冊過的文件對象,比如從監聽可讀變為監聽可寫

  它其實就是 register()  后再跟 unregister() 

  但是使用 modify() 更高效

返回值

  一個 SelectorKey 類的實例

select(timeout=None)

作用

  用於選擇滿足我們監聽的 event 的文件對象

返回值

  是一個 (key, events) 的元組,

  其中 key 是一個 SelectorKey 類的實例,

  而 events  就是  event Mask ( EVENT_READ 或 EVENT_WRITE ,或者二者的組合)

close()

作用

  關閉  selector 

  最后一定要記得調用它, 要確保所有的資源被釋放;

get_key(fileobj)                         

作用

  返回注冊文件對象的  key ;

返回值

  一個 SelectorKey 類的實例;

實例

官方實例

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)

易懂實例

#!/usr/bin/python

import selectors
import socket

# selectors模塊默認會用epoll,如果你的系統中沒有epoll(比如windows)則會自動使用select
sel = selectors.DefaultSelector()  # 生成一個select對象


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)  # 新連接注冊read回調函數


def read(conn, mask):
    data = conn.recv(1024)  # Should be ready
    if data:
        print('echoing', repr(data), 'to', conn)
        conn.send(data)
    else:
        print('closing', conn)
        sel.unregister(conn)
        conn.close()


sock = socket.socket()
sock.bind(('localhost', 8080))
sock.listen()
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)  # 把剛生成的sock連接對象注冊到select連接列表中,並交給accept函數處理

while True:
    events = sel.select()  # 默認是阻塞,有活動連接就返回活動的連接列表
    # 這里看起來是select,其實有可能會使用epoll,如果你的系統支持epoll,那么默認就是epoll
    for key, mask in events:
        callback = key.data  # 去調accept函數
        callback(key.fileobj, mask)  # key.fileobj就是readable中的一個socket連接對象

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM