18.5.2. イベントループ—Pythonドキュメント

提供:Dev Guides
< PythonPython/docs/3.6/library/asyncio-eventloops
移動先:案内検索

18.5.2。 イベントループ

ソースコード: :source: `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

セレクターモジュールに基づくイベントループ。 AbstractEventLoop のサブクラス。

プラットフォームで利用可能な最も効率的なセレクターを使用します。

Windowsでは、ソケットのみがサポートされています(例:パイプはサポートされていません):select MSDNドキュメントを参照してください。

class asyncio.ProactorEventLoop

「I / O完了ポート」(別名IOCP)を使用したWindowsのProactorイベントループ。 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イベントループの一般的な制限:

  • create_unix_connection()およびcreate_unix_server()はサポートされていません。ソケットファミリ socket.AF_UNIX はUNIXに固有です。
  • add_signal_handler()および remove_signal_handler()はサポートされていません
  • EventLoopPolicy.set_child_watcher()はサポートされていません。 ProactorEventLoop はサブプロセスをサポートします。 子プロセスを監視するための実装は1つだけであり、構成する必要はありません。

SelectorEventLoop 固有の制限:

  • SelectSelector が使用されます。これはソケットのみをサポートし、512ソケットに制限されています。
  • add_reader()および add_writer()は、ソケットのファイル記述子のみを受け入れます
  • パイプはサポートされていません(例:connect_read_pipe()connect_write_pipe()
  • サブプロセスはサポートされていません(例:subprocess_exec()subprocess_shell()

ProactorEventLoop 固有の制限:

Windowsの単調時計の解像度は、通常、約15.6ミリ秒です。 最高の解像度は0.5ミリ秒です。 解像度は、ハードウェア( HPET の可用性)とWindowsの構成によって異なります。 非同期遅延呼び出しを参照してください。

バージョン3.5で変更: ProactorEventLoop がSSLをサポートするようになりました。


18.5.2.3.2。 Mac OS X

PTYのようなキャラクターデバイスは、Mavericks(Mac OS 10.9)以降のみ十分にサポートされています。 Mac OS10.5以前ではまったくサポートされていません。

Mac OS 10.6、10.7、および10.8では、デフォルトのイベントループは SelectorEventLoop で、 selectors.KqueueSelector を使用します。 selectors.KqueueSelector は、これらのバージョンのキャラクターデバイスをサポートしていません。 SelectorEventLoopSelectSelector または PollSelector と一緒に使用して、これらのバージョンのMac OSXでキャラクターデバイスをサポートできます。 例:

import asyncio
import selectors

selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)

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

イベントループ管理はポリシーパターンで抽象化され、カスタムプラットフォームとフレームワークに最大限の柔軟性を提供します。 プロセスの実行中、単一のグローバルポリシーオブジェクトが、呼び出しコンテキストに基づいてプロセスで使用可能なイベントループを管理します。 ポリシーは、 AbstractEventLoopPolicy インターフェイスを実装するオブジェクトです。

asyncio のほとんどのユーザーにとって、デフォルトのグローバルポリシーで十分であるため、ポリシーを明示的に処理する必要はありません(以下を参照)。

モジュールレベルの関数 get_event_loop()および set_event_loop()は、デフォルトのポリシーによって管理されるイベントループへの便利なアクセスを提供します。


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

イベントループポリシーは、次のインターフェイスを実装する必要があります。

class asyncio.AbstractEventLoopPolicy

イベントループポリシー。

get_event_loop()

現在のコンテキストのイベントループを取得します。

AbstractEventLoop インターフェイスを実装するイベントループオブジェクトを返します。 コルーチンから呼び出された場合、現在実行中のイベントループを返します。

現在のコンテキストにイベントループが設定されておらず、現在のポリシーでイベントループの作成が指定されていない場合に、例外が発生します。 Noneを返さないでください。

バージョン3.6で変更されました。

set_event_loop(loop)

現在のコンテキストのイベントループを loop に設定します。

new_event_loop()

このポリシーのルールに従って、新しいイベントループオブジェクトを作成して返します。

このループを現在のコンテキストのイベントループとして設定する必要がある場合は、 set_event_loop()を明示的に呼び出す必要があります。

デフォルトのポリシーは、コンテキストを現在のスレッドとして定義し、 asyncio と相互作用するスレッドごとのイベントループを管理します。 現在のスレッドにまだイベントループが関連付けられていない場合、デフォルトポリシーの get_event_loop()メソッドは、メインスレッドから呼び出されたときにイベントループを作成しますが、それ以外の場合は RuntimeError を発生させます。


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

asyncio.get_event_loop_policy()
現在のイベントループポリシーを取得します。
asyncio.set_event_loop_policy(policy)
現在のイベントループポリシーを設定します。 policyNoneの場合、デフォルトのポリシーが復元されます。


18.5.2.7。 イベントループポリシーのカスタマイズ

新しいイベントループポリシーを実装するには、具体的なデフォルトのイベントループポリシーDefaultEventLoopPolicyをサブクラス化し、動作を変更するメソッドをオーバーライドすることをお勧めします。次に例を示します。

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