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 種類の実装のイベントループ、SelectorEventLoopProactorEventLoop を提供しています。

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 のイベントループでの共通の制限:

SelectorEventLoop 固有の制限:

ProactorEventLoop 固有の制限:

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 はこれらのバージョンではキャラクターデバイスをサポートしていません。これらのバージョンでキャラクターデバイスをサポートするには SelectorEventLoopSelectSelector または 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. In case called from coroutine, it returns the currently running event loop.

現在のコンテキストに設定されているイベントループが存在しない場合やイベントループを作成するためのポリシーが指定されていない場合には例外を送出します。 None を返すことがあってはなりません。

バージョン 3.6 で変更.

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)

現在のイベントループポリシーを設定します。policyNone の場合、デフォルトポリシーが復元されます。

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())