イベントループ
**************

**ソースコード:** Lib/asyncio/profile.py と Lib/asyncio/pstats.py

======================================================================

-[ まえがき ]-

イベントループは全ての asyncio アプリケーションの中核をなす存在です。
イベントループは非同期タスクやコールバックを実行し、ネットワーク I/O
を処理し、サブプロセスを実行します。

アプリケーション開発者は通常 "asyncio.run()" のような高水準の ayncio
関数だけを利用し、ループオブジェクトを参照したり、ループオブジェクトの
メソッドを呼び出したりすることはほとんどありません。この節は、イベント
ループの振る舞いに対して細かい調整が必要な、低水準のコード、ライブラリ
、フレームワークの開発者向けです。

-[ イベントループの取得 ]-

以下の低水準関数はイベントループの取得、設定、生成するために使います:

asyncio.get_running_loop()

   現在の OS スレッドで実行中のイベントループを取得します。

   Raise a "RuntimeError" if there is no running event loop.

   This function can only be called from a coroutine or a callback.

   Added in version 3.7.

asyncio.get_event_loop()

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

   When called from a coroutine or a callback (e.g. scheduled with
   call_soon or similar API), this function will always return the
   running event loop.

   If there is no running event loop set, the function will return the
   result of the "get_event_loop_policy().get_event_loop()" call.

   この関数の振る舞いは (特にイベントループポリシーをカスタマイズした
   場合) 複雑なため、コルーチンやコールバックでは "get_event_loop()"
   よりも "get_running_loop()" を使うほうが好ましいと考えられます。

   As noted above, consider using the higher-level "asyncio.run()"
   function, instead of using these lower level functions to manually
   create and close an event loop.

   バージョン 3.14 で変更: Raises a "RuntimeError" if there is no
   current event loop.

   注釈:

     The "asyncio" policy system is deprecated and will be removed in
     Python 3.16; from there on, this function will return the current
     running event loop if present else it will return the loop set by
     "set_event_loop()".

asyncio.set_event_loop(loop)

   *loop* を OS スレッドの現在のイベントループに設定します。

asyncio.new_event_loop()

   新しいイベントループオブジェクトを生成して返します。

"get_event_loop()", "set_event_loop()", および "new_event_loop()" 関数
の振る舞いは、 カスタムイベントループポリシーを設定する ことにより変更
することができます。

-[ 内容 ]-

このページは以下の節から構成されます:

* イベントループのメソッド 節は、イベントループ API のリファレンスです
  。

* コールバックハンドル 節は "loop.call_soon()" や "loop.call_later()"
  などのスケジューリングメソッドが返す "Handle" や "TimerHandle" イン
  スタンスについて解説しています。

* サーバーオブジェクト 節は "loop.create_server()" のようなメソッドが
  返す型について解説しています。

* イベントループの実装 節は "SelectorEventLoop" と "ProactorEventLoop"
  の2つのクラスについて解説しています。

* 使用例 節ではイベントループ API の具体的な使い方を紹介しています。


イベントループのメソッド
========================

イベントループは以下の **低水準な** API を持っています:

* ループの開始と停止

* コールバックのスケジューリング

* 遅延コールバックのスケジューリング

* フューチャーとタスクの生成

* ネットワーク接続の確立

* ネットワークサーバの生成

* ファイルの転送

* TLS へのアップグレード

* ファイル記述子の監視

* ソケットオブジェクトと直接やりとりする

* DNS

* パイプとやりとりする

* Unix シグナル

* スレッドまたはプロセスプールでコードを実行する

* エラーハンドリング API

* デバッグモードの有効化

* サブプロセスの実行


ループの開始と停止
------------------

loop.run_until_complete(future)

   *フューチャー* ("Future" インスタンス) が完了するまで実行します。

   引数が コルーチンオブジェクト の場合、暗黙のうちに "asyncio.Task"
   として実行されるようにスケジュールされます。

   Future の結果を返すか、例外を送出します。

loop.run_forever()

   "stop()" が呼び出されるまでイベントループを実行します。

   "run_forever()" メソッドが呼ばれるより前に "stop()" メソッドが呼ば
   れた場合、イベントループはタイムアウトをゼロにして一度だけ I/O セレ
   クタの問い合わせ処理を行い、 I/O イベントに対してスケジュールされた
   全てのコールバック (および既にスケジュール済みのコールバック) を実
   行したのち、終了します。

   "run_forever()" メソッドを実行中に "stop()" メソッドが呼び出された
   場合、イベントループは現在処理されているすべてのコールバックを実行
   してから終了します。 この場合、コールバックにより新たにスケジュール
   されるコールバックは実行されないことに注意してください; これら新た
   にスケジュールされたコールバックは、次に "run_forever()" または
   "run_until_complete()" が呼び出されたときに実行されます。

loop.stop()

   イベントループを停止します。

loop.is_running()

   イベントループが現在実行中の場合 "True" を返します。

loop.is_closed()

   イベントループが閉じられていた場合 "True" を返します。

loop.close()

   イベントループをクローズします。

   この関数が呼び出される時点で、イベントループが実行中であってはいけ
   ません。保留中のコールバックはすべて破棄されます。

   このメソッドは全てのキューをクリアし、エグゼキューターが実行完了す
   るのを待たずにシャットダウンします。

   このメソッドはべき等 (何回実行しても結果は同じ) であり取り消せませ
   ん。イベントループがクローズされた後、他のいかなるメソッドも呼び出
   すべきではありません。

async loop.shutdown_asyncgens()

   現在オープンになっているすべての *asynchronous generator* (非同期ジ
   ェネレータ) オブジェクトをスケジュールし、 "aclose()" メソッドを呼
   び出すことでそれらをクローズします。 このメソッドの呼び出し後に新し
   い非同期ジェネレータがイテレートされると、イベントループは警告を発
   します。このメソッドはスケジュールされたすべての非同期ジェネレータ
   の終了処理を確実に行うために使用すべきです。

   "asyncio.run()" を使った場合はこの関数を呼び出す必要はありません。

   以下はプログラム例です:

      try:
          loop.run_forever()
      finally:
          loop.run_until_complete(loop.shutdown_asyncgens())
          loop.close()

   Added in version 3.6.

async loop.shutdown_default_executor(timeout=None)

   Schedule the closure of the default executor and wait for it to
   join all of the threads in the "ThreadPoolExecutor". Once this
   method has been called, using the default executor with
   "loop.run_in_executor()" will raise a "RuntimeError".

   The *timeout* parameter specifies the amount of time (in "float"
   seconds) the executor will be given to finish joining. With the
   default, "None", the executor is allowed an unlimited amount of
   time.

   If the *timeout* is reached, a "RuntimeWarning" is emitted and the
   default executor is terminated without waiting for its threads to
   finish joining.

   注釈:

     Do not call this method when using "asyncio.run()", as the latter
     handles default executor shutdown automatically.

   Added in version 3.9.

   バージョン 3.12 で変更: *timeout* 引数が追加されました。


コールバックのスケジューリング
------------------------------

loop.call_soon(callback, *args, context=None)

   イベントループの次のイテレーションで *callback* に指定したコールバ
   ック (*callback*) を *args* 引数で呼び出すようにスケジュールします
   。

   "asyncio.Handle" のインスタンスを返します。このインスタンスを使って
   スケジュールしたコールバックをキャンセルすることができます。

   コールバックは登録された順に呼び出されます。各コールバックは厳密に1
   回だけ呼び出されます。

   The optional keyword-only *context* argument specifies a custom
   "contextvars.Context" for the *callback* to run in. Callbacks use
   the current context when no *context* is provided.

   Unlike "call_soon_threadsafe()", this method is not thread-safe.

loop.call_soon_threadsafe(callback, *args, context=None)

   A thread-safe variant of "call_soon()". When scheduling callbacks
   from another thread, this function *must* be used, since
   "call_soon()" is not thread-safe.

   This function is safe to be called from a reentrant context or
   signal handler, however, it is not safe or fruitful to use the
   returned handle in such contexts.

   すでにクローズされたイベントループに対してこのメソッドが呼び出され
   た場合 "RuntimeError" 例外を送出します。これはメインアプリケーショ
   ンが終了しているにもかかわらずセカンダリスレッドでメソッドが呼び出
   されるといった場合に起こりえます。

   このドキュメントの 並行処理とマルチスレッド処理 節を参照してくださ
   い。

   バージョン 3.7 で変更: キーワード引数 *context* が追加されました。
   詳細は **PEP 567** を参照してください。

注釈:

  ほとんどの "asyncio" モジュールのスケジューリング関数は、キーワード
  引数をコールバックに渡すことを許していません。キーワード引数を渡すた
  めには "functools.partial()" を使ってください:

     # will schedule "print("Hello", flush=True)"
     loop.call_soon(
         functools.partial(print, "Hello", flush=True))

  asyncio は partial オブジェクトのデバッグメッセージやエラーメッセー
  ジをよりよく可視化することができるため、通常はラムダ式よりも partial
  オブジェクトを使う方が便利です。


遅延コールバックのスケジューリング
----------------------------------

イベントループは、コールバック関数を未来のある時点で呼び出されるように
スケジュールする仕組みを提供します。イベントループは時刻が戻らない単調
な時計 (monotonic clock) を使って時刻を追跡します。

loop.call_later(delay, callback, *args, context=None)

   *delay* 秒経過後にコールバック関数 *callback* を呼び出すようにスケ
   ジュールします。 *delay* には整数または浮動小数点数を指定します。

   "asyncio.TimerHandle" のインスタンスを返します。このインスタンスを
   使ってスケジュールしたコールバックをキャンセルすることができます。

   *callback* は厳密に一度だけ呼び出されます。2つのコールバックが完全
   に同じ時間にスケジュールされた場合、呼び出しの順序は未定義です。

   オプションの位置引数 *args* はコールバックが呼び出されるときに位置
   引数として渡されます。キーワード引数を指定してコールバックを呼び出
   したい場合は "functools.partial()" を使用してください。

   オプションのキーワード引数 *context* を使って、コールバック
   *callback* を実行する際のコンテキスト "contextvars.Context" を設定
   することができます。コンテキスト *context* が指定されない場合は現在
   のコンテキストが使われます。

   注釈:

     For performance, callbacks scheduled with "loop.call_later()" may
     run up to one clock-resolution early (see
     "time.get_clock_info('monotonic').resolution").

   バージョン 3.7 で変更: キーワード引数 *context* が追加されました。
   詳細は **PEP 567** を参照してください。

   バージョン 3.8 で変更: Python 3.7 またはそれ以前のバージョンでは、
   デフォルトイベントループの実装を利用した場合に遅延時間 *delay* が1
   日を超えることができませんでした。この問題は Python 3.8 で修正され
   ました。

loop.call_at(when, callback, *args, context=None)

   絶対値の時刻 *when* (整数または浮動小数点数) にコールバックを呼び出
   すようにスケジュールします。 "loop.time()" と同じ参照時刻を使用しま
   す。

   このメソッドの振る舞いは "call_later()" と同じです。

   "asyncio.TimerHandle" のインスタンスを返します。このインスタンスを
   使ってスケジュールしたコールバックをキャンセルすることができます。

   注釈:

     For performance, callbacks scheduled with "loop.call_at()" may
     run up to one clock-resolution early (see
     "time.get_clock_info('monotonic').resolution").

   バージョン 3.7 で変更: キーワード引数 *context* が追加されました。
   詳細は **PEP 567** を参照してください。

   バージョン 3.8 で変更: Python 3.7 またはそれ以前のバージョンでは、
   デフォルトイベントループの実装を利用した場合に現在の時刻と *when*
   との差が1日を超えることができませんでした。この問題は Python 3.8 で
   修正されました。

loop.time()

   現在の時刻を "float" 値で返します。時刻はイベントループが内部で参照
   している時刻が戻らない単調な時計 (monotonic clock) に従います。

注釈:

  バージョン 3.8 で変更: Python 3.7 またはそれ以前のバージョンでは、タ
  イムアウト (相対値 *delay* もしくは絶対値 *when*) は1日を超えること
  ができませんでした。この問題は Python 3.8 で修正されました。

参考: 関数 "asyncio.sleep()"。


フューチャーとタスクの生成
--------------------------

loop.create_future()

   イベントループに接続した "asyncio.Future" オブジェクトを生成します
   。

   asyncio でフューチャーオブジェクトを作成するために推奨される方法で
   す。このメソッドにより、サードパーティ製のイベントループがFutures
   クラスの(パフォーマンスや計測方法が優れた) 代替実装を提供することを
   可能にします。

   Added in version 3.5.2.

loop.create_task(coro, *, name=None, context=None, eager_start=None, **kwargs)

   コルーチン  *coro* の実行をスケジュールします。 "Task" オブジェクト
   を返します。

   サードパーティのイベントループは相互運用のための自身の "Task" のサ
   ブクラスを使用できます。この場合、結果は "Task" のサブクラスになり
   ます。

   The full function signature is largely the same as that of the
   "Task" constructor (or factory) - all of the keyword arguments to
   this function are passed through to that interface.

   *name* 引数が指定され、値が "None" でない場合、 "Task.set_name()"
   メソッドにより *name* がタスクの名前として設定されます。

   省略可能なキーワード引数 *context* によって、*coro* を実行するため
   のカスタムの "contextvars.Context" を指定できます。*context* が省略
   された場合、現在のコンテキストのコピーが作成されます。

   An optional keyword-only *eager_start* argument allows specifying
   if the task should execute eagerly during the call to create_task,
   or be scheduled later. If *eager_start* is not passed the mode set
   by "loop.set_task_factory()" will be used.

   バージョン 3.8 で変更: *name* パラメータを追加しました。

   バージョン 3.11 で変更: *context* パラメータを追加しました。

   バージョン 3.13.3 で変更: Added "kwargs" which passes on arbitrary
   extra parameters, including  "name" and "context".

   バージョン 3.13.4 で変更: Rolled back the change that passes on
   *name* and *context* (if it is None), while still passing on other
   arbitrary keyword arguments (to avoid breaking backwards
   compatibility with 3.13.3).

   バージョン 3.14 で変更: All *kwargs* are now passed on. The
   *eager_start* parameter works with eager task factories.

loop.set_task_factory(factory)

   "loop.create_task()" が使用するタスクファクトリーを設定します。

   If *factory* is "None" the default task factory will be set.
   Otherwise, *factory* must be a *callable* with the signature
   matching "(loop, coro, **kwargs)", where *loop* is a reference to
   the active event loop, and *coro* is a coroutine object.  The
   callable must pass on all *kwargs*, and return a
   "asyncio.Task"-compatible object.

   バージョン 3.13.3 で変更: Required that all *kwargs* are passed on
   to "asyncio.Task".

   バージョン 3.13.4 で変更: *name* is no longer passed to task
   factories. *context* is no longer passed to task factories if it is
   "None".

   バージョン 3.14 で変更: *name* and *context* are now
   unconditionally passed on to task factories again.

loop.get_task_factory()

   タスクファクトリを返します。デフォルトのタスクファクトリを使用中の
   場合は "None" を返します。


ネットワーク接続の確立
----------------------

async loop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, happy_eyeballs_delay=None, interleave=None, all_errors=False)

   *host* と *port* で指定されたアドレスとのストリーミングトランスポー
   ト接続をオープンします。

   ソケットファミリーは *host* (または *family* 引数が与えられた場合は
   *family*) に依存し、 "AF_INET" か "AF_INET6" のいずれかを指定します
   。

   ソケットタイプは "SOCK_STREAM" になります。

   *protocol_factory* は asyncio プロトコル の実装を返す呼び出し可能オ
   ブジェクトでなければなりません。

   このメソッドはバックグラウンドで接続の確立を試みます。成功した場合
   、メソッドは "(transport, protocol)" のペアを返します。

   時系列での下層処理の概要は以下のとおりです:

   1. 接続を確立し、その接続に対する トランスポート が生成されます。

   2. *protocol_factory* が引数なしで呼び出され、ファクトリが プロトコ
      ル インスタンスを返すよう要求します。

   3. プロトコルインスタンスが "connection_made()" メソッドを呼び出す
      ことにより、トランスポートと紐付けられます。

   4. 成功すると "(transport, protocol)" タプルが返されます。

   作成されたトランスポートは実装依存の双方向ストリームです。

   その他の引数:

   * *ssl*: 偽値以外が与えられた場合、SSL/TLS トランスポートが作成され
     ます (デフォルトでは暗号化なしの TCP トランスポートが作成されます
     )。 *ssl* が "ssl.SSLContext" オブジェクトの場合、このコンテキス
     トがトランスポートを作成するために使用されます; *ssl* が "True"
     の場合、 "ssl.create_default_context()" が返すデフォルトのコンテ
     キストが使われます。

     参考: SSL/TLS セキュリティについての考察

   * *server_hostname* は対象サーバーの証明書との一致を確認するための
     ホスト名を設定または上書きします。この引数は *ssl* が "None" でな
     い場合のみ設定すべきです。デフォルトでは *host* に指定したサーバ
     ー名が使用されます。 *host* が空の文字列の場合のデフォルト値は設
     定されていません。その場合、 *server_hostname* を必ず指定してくだ
     さい。 *server_hostname* も空の文字列の場合は、ホスト名の一致確認
     は行われません (これは深刻なセキュリティリスクであり、中間者攻撃
     を受ける可能性があります)。

   * *family*, *proto*, *flags* は任意のアドレスファミリであり、*host*
     解決のための getaddrinfo() 経由で渡されるプロトコルおよびフラグに
     なります。このオプションが与えられた場合、これらはすべて "socket"
     モジュール定数に従った整数でなければなりません。

   * *happy_eyeballs_delay* が設定されると、この接続に対して Happy
     Eyeballs が有効化されます。設定する値は浮動小数点数であり、次の接
     続試行を開始する前に、現在の接続試行が完了するのを待つ時間を秒単
     位で表現します。この値は **RFC 8305** で定義されている "接続試行
     遅延" に相当します。RFC で推奨されている実用的なデフォルト値は
     "0.25" (250 ミリ秒) です。

   * *interleave* はホスト名が複数の IP アドレスに名前解決される場合の
     アドレスの並べ替えを制御します。 "0" または未指定の場合並べ替えは
     行われず、 "getaddrinfo()" が返す順番にしたがってアドレスへの接続
     を試行します。正の整数が指定されると、アドレスはアドレスファミリ
     に応じてインターリーブされます。このとき、与えられた整数は **RFC
     8305** で定義される "最初のアドレスファミリカウント (First
     Address Family Count)" として解釈されます。デフォルト値は、
     *happy_eyeballs_delay* が指定されない場合は "0" であり、指定され
     た場合は "1" です。

   * *sock* を与える場合、トランスポートに使用される、既存の、かつ接続
     済の "socket.socket" オブジェクトを指定します。*sock* を指定する
     場合、*host*、 *port*、 *family*、 *proto*、 *flags*、
     *happy_eyeballs_delay*、 *interleave* および *local_addr* のいず
     れも指定してはいけません。

     注釈:

       The *sock* argument transfers ownership of the socket to the
       transport created. To close the socket, call the transport's
       "close()" method.

   * *local_addr* を与える場合、ソケットをローカルにバインドするために
     使用する "(local_host, local_port)" タプルを指定します。
     *local_host* と *local_port* は、 *host* および *port* と同じく
     "getaddrinfo()" を使ってルックアップされます。

   * *ssl_handshake_timeout* は TLS ハンドシェイクが完了するまでの
     (TLS 接続のための) 待ち時間を秒単位で指定します。指定した待ち時間
     を超えると接続は中断します。 "None" が与えられた場合はデフォルト
     値 "60.0" が使われます。

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   * *all_errors* determines what exceptions are raised when a
     connection cannot be created. By default, only a single
     "Exception" is raised: the first exception if there is only one
     or all errors have same message, or a single "OSError" with the
     error messages combined. When "all_errors" is "True", an
     "ExceptionGroup" will be raised containing all exceptions (even
     if there is only one).

   バージョン 3.5 で変更: "ProactorEventLoop" において SSL/TLS のサポ
   ートが追加されました。

   バージョン 3.6 で変更: 全ての TCP 接続に対してデフォルトでソケット
   オプション socket.TCP_NODELAY  が設定されるようになりました。

   バージョン 3.7 で変更: *ssl_handshake_timeout* 引数が追加されました
   。

   バージョン 3.8 で変更: *happy_eyeballs_delay* と *interleave* が追
   加されました。Happy Eyeballs Algorithm: Success with Dual-Stack
   Hosts. When a server's IPv4 path and protocol are working, but the
   server's IPv6 path and protocol are not working, a dual-stack
   client application experiences significant connection delay
   compared to an IPv4-only client.  This is undesirable because it
   causes the dual-stack client to have a worse user experience.  This
   document specifies requirements for algorithms that reduce this
   user-visible delay and provides an algorithm.詳しくは右記を参照して
   ください: https://datatracker.ietf.org/doc/html/rfc6555

   バージョン 3.11 で変更: *ssl_shutdown_timeout* パラメータが追加され
   ました。

   バージョン 3.12 で変更: *all_errors* が追加されました

   参考:

     "open_connection()" 関数は高水準の代替 API です。この関数は
     ("StreamReader", "StreamWriter") のペアを返し、 async/await コー
     ドから直接使うことができます。

async loop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_port=None, allow_broadcast=None, sock=None)

   データグラム接続 (UDP) を生成します。

   ソケットファミリーは *host* (または *family* 引数が与えられた場合は
   *family*) に依存し、 "AF_INET"、 "AF_INET6"、"AF_UNIX" のいずれかを
   指定します。

   ソケットタイプは "SOCK_DGRAM" になります。

   *protocol_factory* は asyncio プロトコル の実装を返す呼び出し可能オ
   ブジェクトでなければなりません。

   成功すると "(transport, protocol)" タプルが返されます。

   その他の引数:

   * *local_addr* が指定される場合、ソケットをローカルにバインドするた
     めの "(local_host, local_port)" のタプルを指定します。
     *local_host* と *local_port* は "getaddrinfo()" メソッドを使用し
     て検索されます。

     注釈:

       On Windows, when using the proactor event loop with
       "local_addr=None", an "OSError" with "errno.WSAEINVAL" will be
       raised when running it.

   * *remote_addr* が指定される場合、"(remote_host, remote_por)" のタ
     プルで、ソケットをリモートアドレスに束縛するために使用されます。
     *remote_host* と *remote_port* は "getaddrinfo()" を使用して検索
     されます。

   * *family*, *proto*, *flags* は任意のアドレスファミリです。これらの
     ファミリ、プロトコル、フラグは、*host* 解決のため "getaddrinfo()"
     経由でオプションで渡されます。これらのオプションを指定する場合、
     すべて "socket" モジュール定数に従った整数でなければなりません。

   * *reuse_port* は、同じポートにバインドされた既存の端点すべてがこの
     フラグを設定して生成されている場合に限り、この端点を既存の端点と
     同じポートにバインドすることを許可するよう、カーネルに指示します
     （訳註: ソケットのオプション SO_REUSEPORT を使用します）。このオ
     プションは、Windows やいくつかの UNIX システムではサポートされて
     いません。socket.SO_REUSEPORT  定数が定義されていなければ、この機
     能はサポートされません。

   * *allow_broadcast* は、カーネルに、このエンドポイントがブロードキ
     ャストアドレスにメッセージを送信することを許可するように指示しま
     す。

   * オプションの *sock* を指定することで、既存の、すでに接続されてい
     る "socket.socket" をトランスポートで使用することができます。この
     オプションを使用する場合、*local_addr* と *remote_addr* は省略し
     てください ("None" でなければなりません)。

     注釈:

       The *sock* argument transfers ownership of the socket to the
       transport created. To close the socket, call the transport's
       "close()" method.

   UDP echo クライアントプロトコル および UDP echo サーバープロトコル
   の例を参照してください。

   バージョン 3.4.4 で変更: *family*, *proto*, *flags*,
   *reuse_address*, *reuse_port*, *allow_broadcast*, *sock* パラメータ
   が追加されました。

   バージョン 3.8 で変更: Windows サポートが追加されました。

   バージョン 3.8.1 で変更: socket.SO_REUSEADDR の利用が UDP に対して
   重大なセキュリティ上の懸念をもたらすため、 *reuse_address* パラメー
   タはサポートされなくなりました。明示的に "reuse_address=True" を設
   定すると例外を送出します。"SO_REUSEADDR" を使って、同一の UDP ソケ
   ットアドレスに対して複数のプロセスが異なる UID でソケットを割り当て
   ている場合、受信パケットは複数のソケット間にランダムに分散する可能
   性があります。サポートされているプラットフォームでは、 *reuse_port*
   が同様の機能に対する代用品として利用できます。 *reuse_port* は代替
   機能として socket.SO_REUSEPORT を使っており、複数のプロセスが異なる
   UID で同一のソケットに対して割り当てられるのを明確に禁止します。

   バージョン 3.11 で変更: The *reuse_address* parameter, disabled
   since Python 3.8.1, 3.7.6 and 3.6.10, has been entirely removed.

async loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)

   Unix 接続を生成します。

   ソケットファミリーは "AF_UNIX" になります; また、ソケットタイプは
   "SOCK_STREAM" になります。

   成功すると "(transport, protocol)" タプルが返されます。

   *path* は Unix ドメインソケット名で、 *sock* パラメータが指定されな
   い場合は必須です。 抽象 Unix ソケット、 "str"、 "bytes"、 and
   "Path" 形式でのパスがサポートされています。

   このメソッドの引数についての詳細は "loop.create_connection()" メソ
   ッドのドキュメントを参照してください。

   Availability: Unix.

   バージョン 3.7 で変更: Added the *ssl_handshake_timeout* parameter.
   The *path* parameter can now be a *path-like object*.

   バージョン 3.11 で変更: *ssl_shutdown_timeout* パラメータが追加され
   ました。


ネットワークサーバの生成
------------------------

async loop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, keep_alive=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)

   Create a TCP server (socket type "SOCK_STREAM") listening on *port*
   of the *host* address.

   "Server" オブジェクトを返します。

   引数:

   * *protocol_factory* は asyncio プロトコル の実装を返す呼び出し可能
     オブジェクトでなければなりません。

   * *host* パラメータはいくつかの方法で指定することができ、その値によ
     ってサーバーがどこをリッスンするかが決まります。

     * *host* が文字列の場合、 TCP サーバーは *host* で指定した単一の
       ネットワークインターフェースに束縛されます。

     * *host* が文字列のシーケンスである場合、 TCP サーバーはそのシー
       ケンスで指定された全てのネットワークインターフェースに束縛され
       ます。

     * *host* が空の文字列か "None" の場合、すべてのインターフェースが
       想定され、複合的なソケットのリスト (通常は一つが IPv4、もう一つ
       が IPv6) が返されます。

   * The *port* parameter can be set to specify which port the server
     should listen on. If "0" or "None" (the default), a random unused
     port will be selected (note that if *host* resolves to multiple
     network interfaces, a different random port will be selected for
     each interface).

   * *family* can be set to either "socket.AF_INET" or "AF_INET6" to
     force the socket to use IPv4 or IPv6. If not set, the *family*
     will be determined from host name (defaults to "AF_UNSPEC").

   * *flags* は "getaddrinfo()" のためのビットマスクになります。

   * サーバーで既存のソケットオブジェクトを使用するために、オプション
     の引数 *sock* にソケットオブジェクトを設定することができます。指
     定した場合、 *host* と *port* を指定してはいけません。

     注釈:

       The *sock* argument transfers ownership of the socket to the
       server created. To close the socket, call the server's
       "close()" method.

   * *backlog* は "listen()" に渡される、キューに入るコネクションの最
     大数になります (デフォルトは 100)。

   * 確立した接続の上で TLS を有効化するために、 *ssl* に "SSLContext"
     のインスタンスを指定することができます。

   * *reuse_address* は、"TIME_WAIT" 状態にあるローカルソケットを、そ
     の状態が自然にタイムアウトするのを待つことなく再利用するようカー
     ネルに指示します（訳註: ソケットのオプション SO_REUSEADDR を使用
     します）。指定しない場合、UNIX では自動的に "True" が設定されます
     。

   * *reuse_port* は、同じポートにバインドされた既存の端点すべてがこの
     フラグを設定して生成されている場合に限り、この端点を既存の端点と
     同じポートにバインドすることを許可するよう、カーネルに指示します
     （訳註: ソケットのオプション SO_REUSEPORT を使用します）。このオ
     プションは、Windows ではサポートされていません。

   * *keep_alive* set to "True" keeps connections active by enabling
     the periodic transmission of messages.

   バージョン 3.13 で変更: Added the *keep_alive* parameter.

   * *ssl_handshake_timeout* は TLS ハンドシェイクが完了するまでの
     (TLS サーバーのための) 待ち時間を秒単位で指定します。指定した待ち
     時間を超えると接続は中断します。 "None" が与えられた場合はデフォ
     ルト値 "60.0" が使われます。

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   * *start_serving* が "True" に設定された場合 (これがデフォルトです)
     、 生成されたサーバーは即座に接続の受け付けを開始します。 "False"
     が指定された場合、ユーザーは接続の受け付けを開始するために
     "Server.start_serving()" または "Server.serve_forever()" を待ち受
     け (await) る必要があります。

   バージョン 3.5 で変更: "ProactorEventLoop" において SSL/TLS のサポ
   ートが追加されました。

   バージョン 3.5.1 で変更: *host* パラメータに文字列のシーケンスを指
   定できるようになりました。

   バージョン 3.6 で変更: Added *ssl_handshake_timeout* and
   *start_serving* parameters. The socket option socket.TCP_NODELAY is
   set by default for all TCP connections.

   バージョン 3.11 で変更: *ssl_shutdown_timeout* パラメータが追加され
   ました。

   参考:

     "start_server()" 関数は高水準の代替 API です。この関数は
     "StreamReader" と "StreamWriter" のペアを返し、async/await コード
     から使うことができます。

async loop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True, cleanup_socket=True)

   Similar to "loop.create_server()" but works with the "AF_UNIX"
   socket family.

   *path* は Unix ドメインソケット名で、 *sock* パラメータが指定されな
   い場合は必須です。 抽象 Unix ソケット、 "str"、 "bytes"、 and
   "Path" 形式でのパスがサポートされています。

   If *cleanup_socket* is true then the Unix socket will automatically
   be removed from the filesystem when the server is closed, unless
   the socket has been replaced after the server has been created.

   このメソッドの引数についての詳細は "loop.create_server()" メソッド
   のドキュメントを参照してください。

   Availability: Unix.

   バージョン 3.7 で変更: Added the *ssl_handshake_timeout* and
   *start_serving* parameters. The *path* parameter can now be a
   "Path" object.

   バージョン 3.11 で変更: *ssl_shutdown_timeout* パラメータが追加され
   ました。

   バージョン 3.13 で変更: Added the *cleanup_socket* parameter.

async loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)

   すでに確立した接続を transport と protocol のペアでラップします。

   このメソッドは asyncio の範囲外で確立された接続を使うサーバーに対し
   ても使えますが、その場合でも接続は asyncio を使って処理されます。

   引数:

   * *protocol_factory* は asyncio プロトコル の実装を返す呼び出し可能
     オブジェクトでなければなりません。

   * *sock* は "socket.accept" メソッドが返す既存のソケットオブジェク
     トです。

     注釈:

       The *sock* argument transfers ownership of the socket to the
       transport created. To close the socket, call the transport's
       "close()" method.

   * *ssl* には "SSLContext" を指定できます。指定すると、受け付けたコ
     ネクション上での SSL を有効にします。

   * *ssl_handshake_timeout* は SSL ハンドシェイクが完了するまでの
     (SSL 接続のための) 待ち時間を秒単位で指定します。 "None" が与えら
     れた場合はデフォルト値 "60.0" が使われます。

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   "(transport, protocol)" のペアを返します。

   Added in version 3.5.3.

   バージョン 3.7 で変更: *ssl_handshake_timeout* 引数が追加されました
   。

   バージョン 3.11 で変更: *ssl_shutdown_timeout* パラメータが追加され
   ました。


ファイルの転送
--------------

async loop.sendfile(transport, file, offset=0, count=None, *, fallback=True)

   *transport* を通じて *file* を送信します。送信したデータの総バイト
   数を返します。

   このメソッドは、もし利用可能であれば高性能な "os.sendfile()" を利用
   します。

   *file* はバイナリモードでオープンされた通常のファイルオブジェクトで
   なければなりません。

   *offset* はファイルの読み込み開始位置を指定します。 *count* が指定
   された場合、ファイルの EOF までファイルを送信する代わりに、 *count*
   で指定された総バイト数の分だけ送信します。ファイルオブジェクトが指
   し示す位置は、メソッドがエラーを送出した場合でも更新されます。この
   場合実際に送信されたバイト数は "file.tell()" メソッドで取得すること
   ができます。

   *fallback* を "True" に指定することで、 asyncio がプラットフォーム
   が sendfile システムコールをサポートしていない場合 (たとえば
   Windows や Unix の SSL ソケットなど) に別の方法でファイルの読み込み
   と送信を行うようにすることができます。

   システムが *sendfile* システムコールをサポートしておらず、かつ
   *fallback* が "False" の場合、 "SendfileNotAvailableError" 例外を送
   出します。

   Added in version 3.7.


TLS へのアップグレード
----------------------

async loop.start_tls(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)

   既存のトランスポートベースの接続を TLS にアップグレードします。

   Create a TLS coder/decoder instance and insert it between the
   *transport* and the *protocol*. The coder/decoder implements both
   *transport*-facing protocol and *protocol*-facing transport.

   Return the created two-interface instance. After *await*, the
   *protocol* must stop using the original *transport* and communicate
   with the returned object only because the coder caches
   *protocol*-side data and sporadically exchanges extra TLS session
   packets with *transport*.

   In some situations (e.g. when the passed transport is already
   closing) this may return "None".

   引数:

   * *transport* と *protocol* には、 "create_server()" や
     "create_connection()" が返すものと同等のインスタンスを指定します
     。

   * *sslcontext*: 構成済みの "SSLContext" インスタンスです。

   * ("create_server()" で生成されたような) サーバーサイドの接続をアッ
     プグレードする場合は *server_side* に "True" を渡します。

   * *server_hostname*: 対象のサーバーの証明書との照合に使われるホスト
     名を設定または上書きします。

   * *ssl_handshake_timeout* は TLS ハンドシェイクが完了するまでの
     (TLS 接続のための) 待ち時間を秒単位で指定します。指定した待ち時間
     を超えると接続は中断します。 "None" が与えられた場合はデフォルト
     値 "60.0" が使われます。

   * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL
     shutdown to complete before aborting the connection. "30.0"
     seconds if "None" (default).

   Added in version 3.7.

   バージョン 3.11 で変更: *ssl_shutdown_timeout* パラメータが追加され
   ました。


ファイル記述子の監視
--------------------

loop.add_reader(fd, callback, *args)

   ファイル記述子 *fd* に対する読み込みが可能かどうかの監視を開始し、
   *fd* が読み込み可能になると、指定した引数でコールバック *callback*
   を呼び出します。

   Any preexisting callback registered for *fd* is cancelled and
   replaced by *callback*.

loop.remove_reader(fd)

   Stop monitoring the *fd* file descriptor for read availability.
   Returns "True" if *fd* was previously being monitored for reads.

loop.add_writer(fd, callback, *args)

   ファイル記述子 *fd* に対する書き込みが可能かどうかの監視を開始し、
   *fd* が書き込み可能になると、指定した引数でコールバック *callback*
   を呼び出します。

   Any preexisting callback registered for *fd* is cancelled and
   replaced by *callback*.

   コールバック *callback* に キーワード引数を渡す 場合は
   "functools.partial()" を使ってください。

loop.remove_writer(fd)

   Stop monitoring the *fd* file descriptor for write availability.
   Returns "True" if *fd* was previously being monitored for writes.

これらのメソッドに対する制限事項については プラットフォームのサポート
状況 節も参照してください。


ソケットオブジェクトと直接やりとりする
--------------------------------------

一般に、 "loop.create_connection()" や "loop.create_server()" のような
トランスポートベースの API を使ったプロトコルの実装はソケットと直接や
り取りする実装に比べて高速です。しかしながら、パフォーマンスが重要でな
く、直接 "socket" オブジェクトとやりとりした方が便利なユースケースがい
くつかあります。

async loop.sock_recv(sock, nbytes)

   *nbytes* で指定したバイト数までのデータをソケット *sock* から受信し
   ます。 このメソッドは "socket.recv()" の非同期版です。

   受信したデータをバイトオブジェクトとして返します。

   *sock* はノンブロッキングソケットでなければなりません。

   バージョン 3.7 で変更: このメソッドは常にコルーチンメソッドとしてド
   キュメントに記載されてきましたが、 Python 3.7 以前のリリースでは
   "Future" オブジェクトを返していました。 Python 3.7 からは "async
   def" メソッドになりました。

async loop.sock_recv_into(sock, buf)

   ソケット *sock* からデータを受信してバッファ *buf* に格納します。ブ
   ロッキングコードの "socket.recv_into()" メソッドをモデルとしていま
   す。

   バッファに書き込んだデータのバイト数を返します。

   *sock* はノンブロッキングソケットでなければなりません。

   Added in version 3.7.

async loop.sock_recvfrom(sock, bufsize)

   Receive a datagram of up to *bufsize* from *sock*.  Asynchronous
   version of "socket.recvfrom()".

   Return a tuple of (received data, remote address).

   *sock* はノンブロッキングソケットでなければなりません。

   Added in version 3.11.

async loop.sock_recvfrom_into(sock, buf, nbytes=0)

   Receive a datagram of up to *nbytes* from *sock* into *buf*.
   Asynchronous version of "socket.recvfrom_into()".

   Return a tuple of (number of bytes received, remote address).

   *sock* はノンブロッキングソケットでなければなりません。

   Added in version 3.11.

async loop.sock_sendall(sock, data)

   データ *data* をソケット *sock* に送信します。 "socket.sendall()"
   メソッドの非同期版です。

   このメソッドは *data* をすべて送信し終えるか、またはエラーが起きる
   までデータをソケットに送信し続けます。送信に成功した場合 "None" を
   返します。エラーの場合は例外が送出されます。エラーとなった場合、接
   続の受信側で正しく処理されたデータの総量を特定する方法はありません
   。

   *sock* はノンブロッキングソケットでなければなりません。

   バージョン 3.7 で変更: このメソッドは常にコルーチンメソッドとしてド
   キュメントに記載されてきましたが、 Python 3.7 以前のリリースでは
   "Future" オブジェクトを返していました。 Python 3.7 からは "async
   def" メソッドになりました。

async loop.sock_sendto(sock, data, address)

   Send a datagram from *sock* to *address*. Asynchronous version of
   "socket.sendto()".

   Return the number of bytes sent.

   *sock* はノンブロッキングソケットでなければなりません。

   Added in version 3.11.

async loop.sock_connect(sock, address)

   ソケット *sock* をアドレス *address* のリモートソケットに接続します
   。

   "socket.connect()" の非同期版です。

   *sock* はノンブロッキングソケットでなければなりません。

   バージョン 3.5.2 で変更: "address" を名前解決する必要はなくなりまし
   た。 "sock_connect" は "socket.inet_pton()" を呼び出して *address*
   が解決済みかどうかを確認します。未解決の場合、 *address* の名前解決
   には "loop.getaddrinfo()" メソッドが使われます。

   参考: "loop.create_connection()" および  "asyncio.open_connection()"。

async loop.sock_accept(sock)

   接続を受け付けます。ブロッキングコールの "socket.accept()" メソッド
   をモデルとしています。

   ソケットはアドレスに束縛済みで、接続を listen 中である必要がありま
   す。戻り値は "(conn, address)" のペアで、*conn* は接続を通じてデー
   タの送受信を行うための *新しい* ソケットオブジェクト、*address* は
   接続先の端点でソケットに束縛されているアドレスを示します。

   *sock* はノンブロッキングソケットでなければなりません。

   バージョン 3.7 で変更: このメソッドは常にコルーチンメソッドとしてド
   キュメントに記載されてきましたが、 Python 3.7 以前のリリースでは
   "Future" オブジェクトを返していました。 Python 3.7 からは "async
   def" メソッドになりました。

   参考: "loop.create_server()" および "start_server()"。

async loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True)

   ファイルを送信します。利用可能なら高性能な "os.sendfile" を使います
   。送信したデータの総バイト数を返します。

   "socket.sendfile()" メソッドの非同期版です。

   *sock* は "socket.SOCK_STREAM" タイプのノンブロッキングな "socket"
   でなければなりません。

   *file* はバイナリモードでオープンされた通常のファイルオブジェクトで
   なければなりません。

   *offset* はファイルの読み込み開始位置を指定します。 *count* が指定
   された場合、ファイルの EOF までファイルを送信する代わりに、 *count*
   で指定された総バイト数の分だけ送信します。ファイルオブジェクトが指
   し示す位置は、メソッドがエラーを送出した場合でも更新されます。この
   場合実際に送信されたバイト数は "file.tell()" メソッドで取得すること
   ができます。

   *fallback* が "True" に設定された場合、 プラットフォームが sendfile
   システムコールをサポートしていない場合 (たとえば Windows や Unix の
   SSL ソケットなど) に asyncio が別の方法でファイルの読み込みと送信を
   行うようにすることができます。

   システムが *sendfile* システムコールをサポートしておらず、かつ
   *fallback* が "False" の場合、 "SendfileNotAvailableError" 例外を送
   出します。

   *sock* はノンブロッキングソケットでなければなりません。

   Added in version 3.7.


DNS
---

async loop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)

   "socket.getaddrinfo()" の非同期版です。

async loop.getnameinfo(sockaddr, flags=0)

   "socket.getnameinfo()" の非同期版です。

注釈:

  Both *getaddrinfo* and *getnameinfo* internally utilize their
  synchronous versions through the loop's default thread pool
  executor. When this executor is saturated, these methods may
  experience delays, which higher-level networking libraries may
  report as increased timeouts. To mitigate this, consider using a
  custom executor for other user tasks, or setting a default executor
  with a larger number of workers.

バージョン 3.7 で変更: *getaddrinfo* と *getnameinfo* の2つのメソッド
は、いずれも常にコルーチンメソッドとしてドキュメントに記載されてきまし
たが、 Python 3.7 以前のリリースでは、実際には "asyncio.Future" オブジ
ェクトを返していました。 Python 3.7 からはどちらのメソッドもコルーチン
になりました。


パイプとやりとりする
--------------------

async loop.connect_read_pipe(protocol_factory, pipe)

   イベントループの読み込み側終端に *pipe* を登録します。

   *protocol_factory* は asyncio プロトコル の実装を返す呼び出し可能オ
   ブジェクトでなければなりません。

   *pipe* には *file-like オブジェクト* を指定します。

   "(transport, protocol)" のペアを返します。ここで *transport* は
   "ReadTransport" のインターフェースをサポートし、 *protocol* は
   *protocol_factory* ファクトリでインスタンス化されたオブジェクトです
   。

   "SelectorEventLoop" イベントループの場合、*pipe* は非ブロックモード
   に設定されていなければなりません。

async loop.connect_write_pipe(protocol_factory, pipe)

   *pipe* の書き込み側終端をイベントループに登録します。

   *protocol_factory* は asyncio プロトコル の実装を返す呼び出し可能オ
   ブジェクトでなければなりません。

   *pipe* は *file-like オブジェクト* です。

   "(transport, protocol)" のペアを返します。ここで *transport* は
   "WriteTransport" のインスタンスであり、 *protocol* は
   *protocol_factory* ファクトリでインスタンス化されたオブジェクトです
   。

   "SelectorEventLoop" イベントループの場合、*pipe* は非ブロックモード
   に設定されていなければなりません。

注釈:

  "SelectorEventLoop" は Windows 上で上記のメソッドをサポートしていま
  せん。 Windowsでは代わりに "ProactorEventLoop" を使ってください。

参考: "loop.subprocess_exec()" および "loop.subprocess_shell()" メソッド。


Unix シグナル
-------------

loop.add_signal_handler(signum, callback, *args)

   コールバック *callback* をシグナル *signum* に対するハンドラに設定
   します。

   コールバックは *loop*、登録された他のコールバック、およびイベントル
   ープの実行可能なコルーチンから呼び出されます。 "signal.signal()" を
   使って登録されたシグナルハンドラと異なり、この関数で登録されたコー
   ルバックはイベントループと相互作用することが可能です。

   シグナルナンバーが誤っているか捕捉不可能な場合 "ValueError" が送出
   されます。ハンドラーの設定に問題があった場合 "RuntimeError" が送出
   されます。

   コールバック *callback* に キーワード引数を渡す 場合は
   "functools.partial()" を使ってください。

   "signal.signal()" と同じく、この関数はメインスレッドから呼び出され
   なければなりません。

loop.remove_signal_handler(sig)

   シグナル *sig* に対するハンドラを削除します。

   シグナルハンドラが削除された場合 "True" を返します。シグナルに対し
   てハンドラが設定されていない場合には "False" を返します。

   Availability: Unix.

参考: "signal" モジュール。


スレッドまたはプロセスプールでコードを実行する
----------------------------------------------

awaitable loop.run_in_executor(executor, func, *args)

   指定したエグゼキュータで関数 *func* が実行されるように準備します。

   The *executor* argument should be an "concurrent.futures.Executor"
   instance. The default executor is used if *executor* is "None". The
   default executor can be set by "loop.set_default_executor()",
   otherwise, a "concurrent.futures.ThreadPoolExecutor" will be lazy-
   initialized and used by "run_in_executor()" if needed.

   以下はプログラム例です:

      import asyncio
      import concurrent.futures

      def blocking_io():
          # File operations (such as logging) can block the
          # event loop: run them in a thread pool.
          with open('/dev/urandom', 'rb') as f:
              return f.read(100)

      def cpu_bound():
          # CPU-bound operations will block the event loop:
          # in general it is preferable to run them in a
          # process pool.
          return sum(i * i for i in range(10 ** 7))

      async def main():
          loop = asyncio.get_running_loop()

          ## Options:

          # 1. Run in the default loop's executor:
          result = await loop.run_in_executor(
              None, blocking_io)
          print('default thread pool', result)

          # 2. Run in a custom thread pool:
          with concurrent.futures.ThreadPoolExecutor() as pool:
              result = await loop.run_in_executor(
                  pool, blocking_io)
              print('custom thread pool', result)

          # 3. Run in a custom process pool:
          with concurrent.futures.ProcessPoolExecutor() as pool:
              result = await loop.run_in_executor(
                  pool, cpu_bound)
              print('custom process pool', result)

          # 4. Run in a custom interpreter pool:
          with concurrent.futures.InterpreterPoolExecutor() as pool:
              result = await loop.run_in_executor(
                  pool, cpu_bound)
              print('custom interpreter pool', result)

      if __name__ == '__main__':
          asyncio.run(main())

   Note that the entry point guard ("if __name__ == '__main__'") is
   required for option 3 due to the peculiarities of
   "multiprocessing", which is used by "ProcessPoolExecutor". See Safe
   importing of main module.

   このメソッドは "asyncio.Future" オブジェクトを返します。

   関数 *func* に キーワード引数を渡す 場合は "functools.partial()" を
   使ってください。

   バージョン 3.5.3 で変更: "loop.run_in_executor()" は内部で生成する
   スレッドプールエグゼキュータの "max_workers" を設定せず、代わりにス
   レッドプールエグゼキュータ ("ThreadPoolExecutor") にデフォルト値を
   設定させるようになりました。

loop.set_default_executor(executor)

   Set *executor* as the default executor used by "run_in_executor()".
   *executor* must be an instance of "ThreadPoolExecutor", which
   includes "InterpreterPoolExecutor".

   バージョン 3.11 で変更: *executor* must be an instance of
   "ThreadPoolExecutor".


エラーハンドリング API
----------------------

イベントループ内での例外の扱い方をカスタマイズできます。

loop.set_exception_handler(handler)

   *handler* を新しいイベントループ例外ハンドラーとして設定します。

   *handler* が "None" の場合、デフォルトの例外ハンドラが設定されます
   。そうでなければ、 *handler* は "(loop, context)" に一致する関数シ
   グネチャを持った呼び出し可能オブジェクトでなければなりません。ここ
   で "loop" はアクティブなイベントループへの参照であり、 "context" は
   例外の詳細な記述からなる "dict" オブジェクトです (*context* につい
   ての詳細は "call_exception_handler()" メソッドのドキュメントを参照
   してください)。

   If the handler is called on behalf of a "Task" or "Handle", it is
   run in the "contextvars.Context" of that task or callback handle.

   バージョン 3.12 で変更: The handler may be called in the "Context"
   of the task or handle where the exception originated.

loop.get_exception_handler()

   現在の例外ハンドラを返します。カスタム例外ハンドラが設定されていな
   い場合は "None" を返します。

   Added in version 3.5.2.

loop.default_exception_handler(context)

   デフォルトの例外ハンドラーです。

   デフォルト例外ハンドラは、例外ハンドラが未設定の場合、例外が発生し
   た時に呼び出されます。デフォルト例外ハンドラの挙動を受け入れるため
   に、カスタム例外ハンドラから呼び出すことも可能です。

   引数 *context* の意味は "call_exception_handler()" と同じです。

loop.call_exception_handler(context)

   現在のイベントループ例外ハンドラーを呼び出します。

   *context* は以下のキーを含む "dict" オブジェクトです (将来の Python
   バージョンで新しいキーが追加される可能性があります):

   * 'message': エラーメッセージ;

   * 'exception' (任意): 例外オブジェクト;

   * 'future' (任意): "asyncio.Future" インスタンス;

   * 'task' (optional): "asyncio.Task" instance;

   * 'handle' (任意): "asyncio.Handle" インスタンス;

   * 'protocol' (任意): プロトコル インスタンス;

   * 'transport' (任意): トランスポート インスタンス;

   * 'socket' (optional): "socket.socket" instance;

   * 'source_traceback' (optional): Traceback of the source;

   * 'handle_traceback' (optional): Traceback of the handle;

   * 'asyncgen' (optional): Asynchronous generator that caused
        the exception.

   注釈:

     This method should not be overloaded in subclassed event loops.
     For custom exception handling, use the "set_exception_handler()"
     method.


デバッグモードの有効化
----------------------

loop.get_debug()

   イベントループのデバッグモード ("bool") を取得します。

   環境変数 "PYTHONASYNCIODEBUG" に空でない文字列が設定されている場合
   のデフォルト値は "True"、そうでない場合は "False" になります。

loop.set_debug(enabled: bool)

   イベントループのデバッグモードを設定します。

   バージョン 3.7 で変更: 新しい Python 開発モード を使ってデバッグモ
   ードを有効化することができるようになりました。

loop.slow_callback_duration

   This attribute can be used to set the minimum execution duration in
   seconds that is considered "slow". When debug mode is enabled,
   "slow" callbacks are logged.

   Default value is 100 milliseconds.

参考: asyncio のデバッグモード。


サブプロセスの実行
------------------

この節で解説しているのは低水準のメソッドです。通常の async/await コー
ドでは、高水準の関数である "asyncio.create_subprocess_shell()" や
"asyncio.create_subprocess_exec()" を代わりに使うことを検討してくださ
い。

注釈:

  On Windows, the default event loop "ProactorEventLoop" supports
  subprocesses, whereas "SelectorEventLoop" does not. See Subprocess
  Support on Windows for details.

async loop.subprocess_exec(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

   *args* で指定されたひとつの、または複数の文字列引数からサブプロセス
   を生成します。

   *args* は下記のいずれかに当てはまる文字列のリストでなければなりませ
   ん:

   * "str";

   * または ファイルシステムのエンコーディング にエンコードされた
     "bytes"

   引数の最初の文字列はプログラムの実行ファイルを指定します。それに続
   く残りの文字列は引数を指定し、そのプログラムに対する "argv" を構成
   します。

   このメソッドは標準ライブラリの "subprocess.Popen" クラスを、
   "shell=False" かつ最初の引数に文字列のリストを渡して呼び出した場合
   に似ています。しかし、 "Popen" クラスは文字列のリストを引数としてひ
   とつだけ取るのに対して、 *subprocess_exec* は複数の文字列引数をとる
   ことができます。

   *protocol_factory* は "asyncio.SubprocessProtocol" クラスの派生クラ
   スを返す呼び出し可能オブジェクトでなければなりません。

   その他の引数:

   * *stdin* は下記のいずれかをとることができます:

     * a file-like object

     * an existing file descriptor (a positive integer), for example
       those created with "os.pipe()"

     * デフォルト値は "subprocess.PIPE" 定数で、この場合新規にパイプを
       生成して接続します。

     * "None" が設定された場合、サブプロセスは元のプロセスのファイルデ
       スクリプタを引き継ぎます。

     * "subprocess.DEVNULL" 定数を設定すると、特別なファイル
       "os.devnull" を使います。

   * *stdout* は下記のいずれかをとることができます:

     * a file-like object

     * デフォルト値は "subprocess.PIPE" 定数で、この場合新規にパイプを
       生成して接続します。

     * "None" が設定された場合、サブプロセスは元のプロセスのファイルデ
       スクリプタを引き継ぎます。

     * "subprocess.DEVNULL" 定数を設定すると、特別なファイル
       "os.devnull" を使います。

   * *stderr* は下記のいずれかをとることができます:

     * a file-like object

     * デフォルト値は "subprocess.PIPE" 定数で、この場合新規にパイプを
       生成して接続します。

     * "None" が設定された場合、サブプロセスは元のプロセスのファイルデ
       スクリプタを引き継ぎます。

     * "subprocess.DEVNULL" 定数を設定すると、特別なファイル
       "os.devnull" を使います。

     * "subprocess.STDOUT" 定数を設定すると、標準エラー出力ストリーム
       をプロセスの標準出力ストリームに接続します。

   * その他のすべてのキーワード引数は解釈されずにそのまま
     "subprocess.Popen" に渡されます。ただし、 *bufsize*、
     *universal_newlines*、 *shell*、 *text*、 *encoding* および
     *errors* は指定してはいけません。

     "asyncio" のサブプロセス API はストリームからテキストへのデコード
     をサポートしていません。ストリームからテキストに変換するには
     "bytes.decode()" 関数を使ってください。

   If a file-like object passed as *stdin*, *stdout* or *stderr*
   represents a pipe, then the other side of this pipe should be
   registered with "connect_write_pipe()" or "connect_read_pipe()" for
   use with the event loop.

   他の引数についての詳細は "subprocess.Popen" クラスのコンストラクタ
   を参照してください。

   "(transport, protocol)" のペアを返します。ここで *transport* は
   "asyncio.SubprocessTransport" 基底クラスに適合するオブジェクトで、
   *protocol* は *protocol_factory* によりインスタンス化されたオブジェ
   クトです。

   If the transport is closed or is garbage collected, the child
   process is killed if it is still running.

async loop.subprocess_shell(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

   コマンド *cmd* からプラットフォームの "シェル" シンタックスを使って
   サブプロセスを生成します。 *cmd* は "str" 文字列もしくは ファイルシ
   ステムのエンコーディング でエンコードされた "bytes" 文字列です。

   これは標準ライブラリの "subprocess.Popen" クラスを "shell=True" で
   呼び出した場合と似ています。

   *protocol_factory* は "SubprocessProtocol" の派生クラスを返す呼び出
   し可能オブジェクトでなければなりません。

   その他の引数についての詳細は "subprocess_exec()" メソッドを参照して
   ください。

   "(transport, protocol)" のペアを返します。ここで *transport* は
   "SubprocessTransport" 基底クラスに適合するオブジェクトで、
   *protocol* は *protocol_factory* によりインスタンス化されたオブジェ
   クトです。

   If the transport is closed or is garbage collected, the child
   process is killed if it is still running.

注釈:

  シェルインジェクション の脆弱性を回避するために全ての空白文字および
  特殊文字を適切にクオートすることは、アプリケーション側の責任で確実に
  行ってください。シェルコマンドを構成する文字列内の空白文字と特殊文字
  のエスケープは、 "shlex.quote()" 関数を使うと適切に行うことができま
  す。


コールバックのハンドル
======================

class asyncio.Handle

   "loop.call_soon()" や "loop.call_soon_threadsafe()" が返すコールバ
   ックのラッパーです。

   get_context()

      Return the "contextvars.Context" object associated with the
      handle.

      Added in version 3.12.

   cancel()

      コールバックをキャンセルします。コールバックがキャンセル済みまた
      は実行済みの場合、このメソッドは何の影響もありません。

   cancelled()

      コールバックがキャンセルされた場合 "True" を返します。

      Added in version 3.7.

class asyncio.TimerHandle

   A callback wrapper object returned by "loop.call_later()", and
   "loop.call_at()".

   このクラスは "Handle" の派生クラスです。

   when()

      コールバックのスケジュール時刻を秒単位の "float" で返します。

      戻り値の時刻は絶対値で、 "loop.time()" と同じ参照時刻を使って定
      義されています。

      Added in version 3.7.


Serverオブジェクト
==================

Server オブジェクトは "loop.create_server()"、
"loop.create_unix_server()"、 "start_server()" および
"start_unix_server()" 関数により生成されます。

Do not instantiate the "Server" class directly.

class asyncio.Server

   *Server* オブジェクトは非同期のコンテキストマネージャです。 "async
   with" 文の中で使われた場合、 "async with" 文が完了した時に Server
   オブジェクトがクローズされること、およびそれ以降に接続を受け付けな
   いことが保証されます。

      srv = await loop.create_server(...)

      async with srv:
          # some code

      # At this point, srv is closed and no longer accepts new connections.

   バージョン 3.7 で変更: Python 3.7 から、 Server オブジェクトは非同
   期のコンテキストマネージャになりました。

   バージョン 3.11 で変更: This class was exposed publicly as
   "asyncio.Server" in Python 3.9.11, 3.10.3 and 3.11.

   close()

      サーバーを停止します: 待機しているソケットをクローズし "sockets"
      属性に "None" を設定します。

      既存の受信中のクライアントとの接続を表すソケットはオープンのまま
      です。

      The server is closed asynchronously; use the "wait_closed()"
      coroutine to wait until the server is closed (and no more
      connections are active).

   close_clients()

      Close all existing incoming client connections.

      Calls "close()" on all associated transports.

      "close()" should be called before "close_clients()" when closing
      the server to avoid races with new clients connecting.

      Added in version 3.13.

   abort_clients()

      Close all existing incoming client connections immediately,
      without waiting for pending operations to complete.

      Calls "abort()" on all associated transports.

      "close()" should be called before "abort_clients()" when closing
      the server to avoid races with new clients connecting.

      Added in version 3.13.

   get_loop()

      サーバオブジェクトに付随するイベントループを返します。

      Added in version 3.7.

   async start_serving()

      接続の受け付けを開始します。

      This method is idempotent, so it can be called when the server
      is already serving.

      キーワード専用のパラメータ *start_serving* を
      "loop.create_server()" や "asyncio.start_server()" メソッドに対
      して使用することにより、初期に接続を受け付けない Server オブジェ
      クトを生成することができます。この場合 "Server.start_serving()"
      または "Server.serve_forever()" メソッドを使ってオブジェクトが接
      続の受け付けを開始するようにすることができます。

      Added in version 3.7.

   async serve_forever()

      接続の受け入れを開始し、コルーチンがキャンセルされるまで継続しま
      す。 "serve_forever" タスクのキャンセルによりサーバーもクローズ
      されます。

      このメソッドはサーバーがすでに接続の受け入れを開始していても呼び
      出し可能です。ひとつの *Server* オブジェクトにつき
      "serve_forever" タスクはひとつだけ存在できます。

      以下はプログラム例です:

         async def client_connected(reader, writer):
             # Communicate with the client with
             # reader/writer streams.  For example:
             await reader.readline()

         async def main(host, port):
             srv = await asyncio.start_server(
                 client_connected, host, port)
             await srv.serve_forever()

         asyncio.run(main('127.0.0.1', 0))

      Added in version 3.7.

   is_serving()

      サーバーが新規に接続の受け入れを開始した場合 "True" を返します。

      Added in version 3.7.

   async wait_closed()

      Wait until the "close()" method completes and all active
      connections have finished.

   sockets

      List of socket-like objects, "asyncio.trsock.TransportSocket",
      which the server is listening on.

      バージョン 3.7 で変更: Python 3.7 より前のバージョンでは、
      "Server.sockets" は内部に持っているサーバーソケットのリストを直
      接返していました。 Python 3.7 ではリストのコピーが返されるように
      なりました。


イベントループの実装
====================

asyncio は2つの異なるイベントループの実装、 "SelectorEventLoop" と
"ProactorEventLoop"、 を提供します:

By default asyncio is configured to use "EventLoop".

class asyncio.SelectorEventLoop

   A subclass of "AbstractEventLoop" based on the "selectors" module.

   プラットフォーム上で利用可能な最も効率の良い *selector* を使います
   。特定のセレクタ実装を使うように手動で構成することも可能です:

      import asyncio
      import selectors

      async def main():
         ...

      loop_factory = lambda: asyncio.SelectorEventLoop(selectors.SelectSelector())
      asyncio.run(main(), loop_factory=loop_factory)

   Availability: Unix, Windows.

class asyncio.ProactorEventLoop

   A subclass of "AbstractEventLoop" for Windows that uses "I/O
   Completion Ports" (IOCP).

   Availability: Windows.

   参考: MSDN documentation on I/O Completion Ports.

class asyncio.EventLoop

      An alias to the most efficient available subclass of
      "AbstractEventLoop" for the given platform.

      It is an alias to "SelectorEventLoop" on Unix and
      "ProactorEventLoop" on Windows.

   Added in version 3.13.

class asyncio.AbstractEventLoop

   asyncio に適合するイベントループの抽象基底クラスです。

   The イベントループのメソッド section lists all methods that an
   alternative implementation of "AbstractEventLoop" should have
   defined.


使用例
======

この節の全ての使用例は **意図的に**  "loop.run_forever()" や
"loop.call_soon()" のような 低水準のイベントループ API の使用法を示し
ています。一方で現代的な asyncio アプリケーションはここに示すような方
法をほとんど必要としません。 "asyncio.run()" のような高水準の関数の使
用を検討してください。


call_soon() を使った Hello World
--------------------------------

"loop.call_soon()" メソッドを使ってコールバックをスケジュールする例で
す。コールバックは ""Hello World"" を出力しイベントループを停止します:

   import asyncio

   def hello_world(loop):
       """A callback to print 'Hello World' and stop the event loop"""
       print('Hello World')
       loop.stop()

   loop = asyncio.new_event_loop()

   # Schedule a call to hello_world()
   loop.call_soon(hello_world, loop)

   # Blocking call interrupted by loop.stop()
   try:
       loop.run_forever()
   finally:
       loop.close()

参考: コルーチンと "run()" 関数を使用した同じような Hello World の例。


call_later() で現在の日時を表示する
-----------------------------------

毎秒現在時刻を表示するコールバックの例です。コールバックは
"loop.call_later()" メソッドを使って自身を5秒後に実行するよう再スケジ
ュールし、イベントループを停止します:

   import asyncio
   import datetime

   def display_date(end_time, loop):
       print(datetime.datetime.now())
       if (loop.time() + 1.0) < end_time:
           loop.call_later(1, display_date, end_time, loop)
       else:
           loop.stop()

   loop = asyncio.new_event_loop()

   # Schedule the first call to display_date()
   end_time = loop.time() + 5.0
   loop.call_soon(display_date, end_time, loop)

   # Blocking call interrupted by loop.stop()
   try:
       loop.run_forever()
   finally:
       loop.close()

参考: コルーチンと "run()" 関数を使用した同じような 現在時刻出力 の例。


読み込みイベント用ファイル記述子の監視
--------------------------------------

ファイル記述子が "loop.add_reader()" メソッドを使って何らかのデータを
受信するまで待機し、その後イベントループをクローズします:

   import asyncio
   from socket import socketpair

   # Create a pair of connected file descriptors
   rsock, wsock = socketpair()

   loop = asyncio.new_event_loop()

   def reader():
       data = rsock.recv(100)
       print("Received:", data.decode())

       # We are done: unregister the file descriptor
       loop.remove_reader(rsock)

       # Stop the event loop
       loop.stop()

   # Register the file descriptor for read event
   loop.add_reader(rsock, reader)

   # Simulate the reception of data from the network
   loop.call_soon(wsock.send, 'abc'.encode())

   try:
       # Run the event loop
       loop.run_forever()
   finally:
       # We are done. Close sockets and the event loop.
       rsock.close()
       wsock.close()
       loop.close()

参考:

  * トランスポート、プロトコル、および "loop.create_connection()" メソ
    ッドを使用した同じような 例。

  * 高水準の "asyncio.open_connection()" 関数とストリームを使用したも
    うひとつの 実装例。


SIGINT および SIGTERM 用のシグナルハンドラーの設定
--------------------------------------------------

(ここに挙げる "signals" の例は Unix でのみ動きます。)

Register handlers for signals "SIGINT" and "SIGTERM" using the
"loop.add_signal_handler()" method:

   import asyncio
   import functools
   import os
   import signal

   def ask_exit(signame, loop):
       print("got signal %s: exit" % signame)
       loop.stop()

   async def main():
       loop = asyncio.get_running_loop()

       for signame in {'SIGINT', 'SIGTERM'}:
           loop.add_signal_handler(
               getattr(signal, signame),
               functools.partial(ask_exit, signame, loop))

       await asyncio.sleep(3600)

   print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
   print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")

   asyncio.run(main())
