18.5.2. イベントループ¶
ソースコード: Lib/asyncio/events.py
18.5.2.1. イベントループ関数¶
以下の関数は、グローバルポリシーのメソッドにアクセスするための便利なショートカットです。これらはデフォルトポリシーへのアクセス手段を提供するものであり、プロセスの実行前に set_event_loop_policy()
を呼び出して設定された代替ポリシーには適用できないことに注意してください。
-
asyncio.
get_event_loop
()¶ get_event_loop_policy().get_event_loop()
の呼び出しと等価です。
-
asyncio.
set_event_loop
(loop)¶ get_event_loop_policy().set_event_loop(loop)
の呼び出しと等価です。
-
asyncio.
new_event_loop
()¶ get_event_loop_policy().new_event_loop()
の呼び出しと等価です。
18.5.2.2. 利用可能なイベントループ¶
asyncio は現在 2 種類の実装のイベントループ、SelectorEventLoop
と ProactorEventLoop
を提供しています。
-
class
asyncio.
SelectorEventLoop
¶ selectors
モジュールベースのイベントループで、AbstractEventLoop
のサブクラスです。プラットフォームで利用できる最も効率的なセレクターを使用します。
Windows ではソケットのみサポートされています (例えばパイプは未サポート): MSDN の select のドキュメント を参照してください。
-
class
asyncio.
ProactorEventLoop
¶ "I/O Completion Ports" (IOCP) を使用した Windows 用のプロアクターイベントループで、
AbstractEventLoop
のサブクラスです。利用できる環境 : Windows.
Windows で ProactorEventLoop
を使用した例:
import asyncio, sys
if sys.platform == 'win32':
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
18.5.2.3. プラットフォームでのサポート¶
asyncio
モジュールは移植性を考慮して設計されていますが、プラットフォームごとにわずかな違いがあり、asyncio
の全機能をサポートしているわけではありません。
18.5.2.3.1. Windows¶
Windows のイベントループでの共通の制限:
create_unix_connection()
およびcreate_unix_server()
はサポートされていません: ソケットファミリーsocket.AF_UNIX
は UNIX 固有ですadd_signal_handler()
とremove_signal_handler()
はサポートされていませんEventLoopPolicy.set_child_watcher()
は未サポート:ProactorEventLoop
はサブプロセスをサポートします。これは子プロセスを監視できる唯一の実装で、構成設定を必要としません。
SelectorEventLoop
固有の制限:
SelectSelector
が使用されるがサポートしているのはソケットのみで 512 ソケットに制限されるadd_reader()
およびadd_writer()
はソケットのファイル記述子受け取るだけです- パイプは未サポート (例:
connect_read_pipe()
,connect_write_pipe()
) - サブプロセス は未サポート (例:
subprocess_exec()
,subprocess_shell()
)
ProactorEventLoop
固有の制限:
create_datagram_endpoint()
(UDP) は未サポートadd_reader()
およびadd_writer()
は未サポート
Windows のモノトニック時計の時間分解能は、通常約 15.6 秒です。 最高分解能は 0.5 秒です。 分解能はハードウェア (HPET の可否) および Windows の設定に依存します。 asyncio 遅延呼び出し を参照してください。
バージョン 3.5 で変更: ProactorEventLoop
は SSL をサポートしました。
18.5.2.3.2. Mac OS X¶
PTY のようなキャラクターデバイスは Mavericks (Mac OS 10.9) 以降でのみ十分サポートされています。Mac OS 10.5 以前ではサポートされていません。
Mac OS 10.6、10.7 および 10.8 では、デフォルトのイベントループは SelectorEventLoop
で、selectors.KqueueSelector
を使用します。selectors.KqueueSelector
はこれらのバージョンではキャラクターデバイスをサポートしていません。これらのバージョンでキャラクターデバイスをサポートするには SelectorEventLoop
で SelectSelector
または PollSelector
を使用します。例:
import asyncio
import selectors
selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)
18.5.2.4. イベントループのポリシーとデフォルトポリシー¶
イベントループの管理は、カスタムプラットフォームやフレームワークのために最大限の柔軟性を提供するため ポリシー パターンによって抽象化されます。プロセスの実行中、単一のポリシーオブジェクトが、コンテキスト呼び出しベースのプロセスから利用可能なイベントループを管理します。一つのポリシーは一つの AbstractEventLoopPolicy
インターフェースを実装するオブジェクトです。
For most users of asyncio
, policies never have to be dealt with
explicitly, since the default global policy is sufficient (see below).
The module-level functions
get_event_loop()
and set_event_loop()
provide convenient access to
event loops managed by the default policy.
18.5.2.5. イベントループポリシーインターフェース¶
イベントループのポリシーは以下のインターフェースを実装しなければなりません:
-
class
asyncio.
AbstractEventLoopPolicy
¶ イベントループポリシーです。
-
get_event_loop
()¶ 現在のコンテクストのイベントループを取得します。
Returns an event loop object implementing the
AbstractEventLoop
interface.現在のコンテキストに設定されているイベントループが存在しない場合やイベントループを作成するためのポリシーが指定されていない場合には例外を送出します。
None
を返すことがあってはなりません。
-
set_event_loop
(loop)¶ 現在のコンテキストにイベントループ loop を設定します。
-
new_event_loop
()¶ このポリシーのルールに従った新しいイベントループを作成して返します。
このループを現在のコンテキストのイベントループとして設定する必要がある場合は、
set_event_loop()
が明示的に呼び出されなくてはなりません。
-
The default policy defines context as the current thread, and manages an event
loop per thread that interacts with asyncio
. If the current thread
doesn’t already have an event loop associated with it, the default policy’s
get_event_loop()
method creates one when
called from the main thread, but raises RuntimeError
otherwise.
18.5.2.6. グローバルループポリシーへのアクセス¶
-
asyncio.
get_event_loop_policy
()¶ 現在のイベントループポリシーを取得します。
-
asyncio.
set_event_loop_policy
(policy)¶ 現在のイベントループポリシーを設定します。policy が
None
の場合、デフォルトポリシーが復元されます。
18.5.2.7. Customizing the event loop policy¶
To implement a new event loop policy, it is recommended you subclass the
concrete default event loop policy DefaultEventLoopPolicy
and override the methods for which you want to change behavior, for example:
class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
def get_event_loop(self):
"""Get the event loop.
This may be None or an instance of EventLoop.
"""
loop = super().get_event_loop()
# Do something with loop ...
return loop
asyncio.set_event_loop_policy(MyEventLoopPolicy())