イベントループ

ソースコード: Lib/asyncio/events.py

イベントループ関数

以下の関数は、グローバルポリシーのメソッドにアクセスするための便利なショートカットです。これらはデフォルトポリシーへのアクセス手段を提供するものであり、プロセスの実行前に 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() の呼び出しと等価です。

asyncio.get_running_loop()

Return the running event loop in the current OS thread. If there is no running event loop a RuntimeError is raised.

バージョン 3.7 で追加.

利用可能なイベントループ

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)

プラットフォームでのサポート

asyncio モジュールは移植性を考慮して設計されていますが、プラットフォームごとにわずかな違いがあり、asyncio の全機能をサポートしているわけではありません。

Windows

Windows のイベントループでの共通の制限:

SelectorEventLoop 固有の制限:

ProactorEventLoop 固有の制限:

Windows のモノトニック時計の時間分解能は、通常約 15.6 秒です。 最高分解能は 0.5 秒です。 分解能はハードウェア (HPET の可否) および Windows の設定に依存します。 asyncio 遅延呼び出し を参照してください。

バージョン 3.5 で変更: ProactorEventLoop は SSL をサポートしました。

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)

イベントループのポリシーとデフォルトポリシー

イベントループの管理は、カスタムプラットフォームやフレームワークのために最大限の柔軟性を提供するため ポリシー パターンによって抽象化されます。プロセスの実行中、単一のポリシーオブジェクトが、コンテキスト呼び出しベースのプロセスから利用可能なイベントループを管理します。一つのポリシーは一つの 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.

イベントループポリシーインターフェース

イベントループのポリシーは以下のインターフェースを実装しなければなりません:

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. An exception to this rule happens when get_event_loop() is called from a running future/coroutine, in which case it will return the current loop running that future/coroutine.

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.

グローバルループポリシーへのアクセス

asyncio.get_event_loop_policy()

現在のイベントループポリシーを取得します。

asyncio.set_event_loop_policy(policy)

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

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