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 そのファイルオブジェクトで準備できたイベントのビットマスクです。注釈
This method can return before any file object becomes ready or the timeout has elapsed if the current process receives a signal: in this case, an empty list will be returned.
バージョン 3.5 で変更: The selector is now retried with a recomputed timeout when interrupted by a signal if the signal handler did not raise an exception (see PEP 475 for the rationale), instead of returning an empty list of events before the timeout.
-
close()¶ セレクタを閉じます。
下層の資源が解放されたこと保証するために呼ばれなければなりません。 セレクタは一旦閉じられると使ってはいけません。
-
get_key(fileobj)¶ 登録されたファイルオブジェクトに関連付けられたキーを返します。
そのファイルオブジェクトに関連付けられた
SelectorKeyインスタンスを返します。そのファイルオブジェクトが登録されていない場合KeyErrorを送出します。
-
abstractmethod
get_map()¶ ファイルオブジェクトからセレクタキーへのマッピングを返します。
This returns a
Mappinginstance mapping registered file objects to their associatedSelectorKeyinstance.
-
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)
