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.

   参考: MSDN の I/O Completion Ports のドキュメント。

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

   現在のイベントループポリシーを設定します。*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())
