18.4. selectors
--- 高水準の I/O 多重化¶
バージョン 3.4 で追加.
ソースコード: Lib/selectors.py
18.4.1. はじめに¶
このモジュールにより、select
モジュールプリミティブに基づく高水準かつ効率的な I/O の多重化が行えます。OS 水準のプリミティブを使用した正確な制御を求めない限り、このモジュールの使用が推奨されます。
このモジュールは BaseSelector
抽象基底クラスと、いくつかの具象実装 (KqueueSelector
, EpollSelector
...) を定義しており、これらは複数のファイルオブジェクトの I/O の準備状況の通知の待機に使用できます。以下では、 "ファイルオブジェクト" は、fileno()
メソッドを持つあらゆるオブジェクトか、あるいは Raw ファイル記述子を意味します。ファイルオブジェクト を参照してください。
DefaultSelector
は、現在のプラットフォームで利用できる、もっとも効率的な実装の別名になります: これはほとんどのユーザーにとってのデフォルトの選択になるはずです。
注釈
プラットフォームごとにサポートされているファイルオブジェクトのタイプは異なります: Windows ではソケットはサポートされますが、パイプはされません。Unix では両方がサポートされます (その他の fifo やスペシャルファイルデバイスなどのタイプもサポートされます)。
参考
select
- 低水準の I/O 多重化モジュールです。
18.4.2. クラス¶
クラス階層:
BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector
以下では、events は与えられたファイルオブジェクトを待機すべき I/O イベントを示すビット単位のマスクになります。これには以下のモジュール定数の組み合わせを設定できます:
定数 意味 EVENT_READ
読み込み可能 EVENT_WRITE
書き込み可能
-
class
selectors.
SelectorKey
¶ SelectorKey
はそれの下層のファイルディスクリプタ、選択したイベントマスク、および付属データへのファイルオブジェクトの関連付けに使用されるnamedtuple
です。いくつかのBaseSelector
メソッドを返します。-
fileobj
¶ 登録されたファイルオブジェクトです。
-
fd
¶ 下層のファイル記述子です。
-
events
¶ このファイルオブジェクトで待機しなければならないイベントです。
-
data
¶ このファイルオブジェクトに関連付けられたオプションの不透明型 (Opaque) データです。例えば、これはクライアントごとのセッション ID を格納するために使用できます。
-
-
class
selectors.
BaseSelector
¶ BaseSelector
は複数のファイルオブジェクトの I/O イベントの準備状況の待機に使用されます。これはファイルストリームを登録、登録解除、およびこれらのストリームでの I/O イベントを待機 (オプションでタイムアウト) するメソッドをサポートします。これは抽象基底クラスであるため、インスタンスを作成できません。使用する実装を明示的に指定したい、そしてプラットフォームがそれをサポートしている場合は、代わりにDefaultSelector
を使用するか、SelectSelector
やKqueueSelector
などの一つを使用します。BaseSelector
とその具象実装は コンテキストマネージャー プロトコルをサポートしています。-
abstractmethod
register
(fileobj, events, data=None)¶ I/O イベントを監視するファイルオブジェクトをセレクションに登録します。
fileobj は監視するファイルオブジェクトです。これは整数のファイル記述子か、
fileno()
メソッドを持つオブジェクトのどちらかになります。events は監視するイベントのビット幅マスクになります。data は不透明型 (Opaque) オブジェクトです。これは新しい
SelectorKey
インスタンスを返します。不正なイベントマスク化ファイル記述子のときはValueError
が、ファイルオブジェクトがすでに登録済みのときはKeyError
が送出されます。
-
abstractmethod
unregister
(fileobj)¶ ファイルオブジェクトのセレクション登録を解除し、監視対象から外します。ファイルオブジェクトの登録解除はそのクローズより前に行われます。
fileobj は登録済みのファイルオブジェクトでなければなりません。
関連付けられた
SelectorKey
インスタンスを返します。fileobj が登録されていない場合KeyError
を送出します。fileobj が不正な場合 (例えば fileobj にfileno()
メソッドが無い場合やfileno()
メソッドの戻り値が不正な場合)ValueError
を送出します。
-
modify
(fileobj, events, data=None)¶ 登録されたファイルオブジェクトの監視されたイベントや付属データを変更します。
より効率的に実装できる点を除けば、
BaseSelector.unregister(fileobj)()
に続けてBaseSelector.register(fileobj, events, data)()
を行うのと等価です。新たな
SelectorKey
インスタンスを返します。 イベントマスクやファイル記述子が不正な場合はValueError
を、ファイルオブジェクトが登録されていない場合はKeyError
を送出します。
-
abstractmethod
select
(timeout=None)¶ 登録されたいくつかのファイルオブジェクトが準備できたか、タイムアウトするまで待機します。
timeout > 0
の場合、最大待機時間を秒で指定します。timeout <= 0
の場合、この関数の呼び出しはブロックせず、 現在準備できているファイルオブジェクトを報告します。 timeout がNone
の場合、監視しているファイルオブジェクトの一つが準備できるまでブロックします。この関数は
(key, events)
タプルのリストを返します。準備できたファイルオブジェクトにつき1タプルです。key は準備状態のファイルオブジェクトに対応する
SelectorKey
インスタンスです。 events はそのファイルオブジェクトで準備が完了したイベントのビットマスクです。注釈
このメソッドは、現在のプロセスで信号を受信した場合、どのファイルオブジェクトも準備完了にならないうちに、またはタイムアウトが経過する前に返ることがあります。その場合、空のリストが返されます。
バージョン 3.5 で変更: このセレクタは、シグナルによって中断された時に、シグナルハンドラが例外を起こさなかった場合、空のイベントリストを返すのではなく、再計算されたタイムアウトによってリトライするようになりました (この論拠については PEP 475 を参照してください)。
-
close
()¶ セレクタを閉じます。
下層のリソースがすべて解放されたことを確かめるために呼ばれなければなりません。一旦閉じられたセレクタは使ってはいけません。
-
get_key
(fileobj)¶ 登録されたファイルオブジェクトに関連付けられたキーを返します。
そのファイルオブジェクトに関連付けられた
SelectorKey
インスタンスを返します。そのファイルオブジェクトが登録されていない場合KeyError
を送出します。
-
abstractmethod
get_map
()¶ ファイルオブジェクトからセレクタキーへのマッピングを返します。
これは、登録済みのファイルオブジェクトを、それらに関連づけられた
SelectorKey
インスタンスにマッピングするMapping
のインスタンスを返します。
-
abstractmethod
-
class
selectors.
DefaultSelector
¶ デフォルトの selector クラスで、現在のプラットフォームで利用できる最も効率的な実装を使用しています。大半のユーザはこれをデフォルトにすべきです。
-
class
selectors.
SelectSelector
¶ select.select()
を基底とするセレクタです。
-
class
selectors.
PollSelector
¶ select.poll()
を基底とするセレクタです。
-
class
selectors.
EpollSelector
¶ select.epoll()
を基底とするセレクタです。-
fileno
()¶ 下層の
select.epoll()
オブジェクトが使用しているファイル記述子を返します。
-
-
class
selectors.
DevpollSelector
¶ select.devpoll()
を基底とするセレクタです。-
fileno
()¶ 下層の
select.devpoll()
オブジェクトが使用しているファイル記述子を返します。
バージョン 3.5 で追加.
-
-
class
selectors.
KqueueSelector
¶ select.kqueue()
を基底とするセレクタです。-
fileno
()¶ 下層の
select.kqueue()
オブジェクトが使用しているファイル記述子を返します。
-
18.4.3. 使用例¶
簡単なエコーサーバの実装です:
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)