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

**ソースコード:** 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.

   バージョン 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.

   注釈:

     In Python versions 3.10.0--3.10.8 and 3.11.0 this function (and
     other functions which use it implicitly) emitted a
     "DeprecationWarning" if there was no running event loop, even if
     the current loop was set on the policy. In Python versions
     3.10.9, 3.11.1 and 3.12 they emit a "DeprecationWarning" if there
     is no running event loop and no current loop is set. In some
     future Python release this will become an error.

asyncio.set_event_loop(loop)

   Set *loop* as the current event loop for the current OS thread.

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

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

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

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

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

coroutine loop.shutdown_asyncgens()

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

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

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

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

   バージョン 3.6 で追加.

coroutine loop.shutdown_default_executor()

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

   注釈:

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

   バージョン 3.9 で追加.


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

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

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

   Return an instance of "asyncio.Handle", which can be used later to
   cancel the callback.

   コールバックは登録された順に呼び出されます。各コールバックは厳密に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.

   すでにクローズされたイベントループに対してこのメソッドが呼び出され
   た場合 "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* が指定されない場合は現在
   のコンテキストが使われます。

   バージョン 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" のインスタンスを返します。このインスタンスを
   使ってスケジュールしたコールバックをキャンセルすることができます。

   バージョン 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
   クラスの(パフォーマンスや計測方法が優れた) 代替実装を提供することを
   可能にします。

   バージョン 3.5.2 で追加.

loop.create_task(coro, *, name=None)

   Schedule the execution of coroutine *coro*. Return a "Task" object.

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

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

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

loop.set_task_factory(factory)

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

   *factory* が "None" の場合、デフォルトのタスクファクトリーが設定さ
   れます。そうでなければ、 *factory* は "(loop, coro)" に一致する関数
   シグネチャを持った *呼び出し可能オブジェクト* でなければなりません
   。ここで *loop* はアクティブなイベントループへの参照であり、 *coro*
   はコルーチンオブジェクトです。呼び出し可能オブジェクトは
   "asyncio.Future" と互換性のあるオブジェクトを返さなければなりません
   。

loop.get_task_factory()

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


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

coroutine 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, happy_eyeballs_delay=None, interleave=None)

   *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" が使われます。

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

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

   バージョン 3.7 で変更: Added the *ssl_handshake_timeout* parameter.

   バージョン 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://tools.ietf.org/html/rfc6555

   参考:

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

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

   注釈:

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

   データグラム接続 (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()" メソッドを使用し
     て検索されます。

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

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

   * *reuse_port* は、同じポートにバインドされた既存の端点すべてがこの
     フラグを設定して生成されている場合に限り、この端点を既存の端点と
     同じポートにバインドすることを許可するよう、カーネルに指示します
     （訳註: ソケットのオプション SO_REUSEPORT を使用します）。このオ
     プションは、Windows やいくつかの UNIX システムではサポートされて
     いません。"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.1 で変更: セキュリティ上の懸念により、
   *reuse_address* パラメータはサポートされなくなりました。

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

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

   Unix 接続を生成します。

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

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

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

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

   利用可能な環境: Unix。

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


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

coroutine 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, ssl_handshake_timeout=None, start_serving=True)

   アドレス *host* のポート *port* をリッスンする (ソケットタイプが
   "SOCK_STREAM" である) TCP サーバーを生成します。

   "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* に "socket.AF_INET" または "AF_INET6" を指定することによ
     り、ソケットでそれぞれ IPv4 または IPv6 の使用を強制することがで
     きます。設定されない場合、 *family* はホスト名から決定されます
     ("socket.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 ではサポートされていません。

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

   * *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 "TCP_NODELAY" is set
   by default for all TCP connections.

   参考:

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

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

   "loop.create_server()" と似ていますが、 "AF_UNIX" ソケットファミリ
   ーとともに動作します。

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

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

   利用可能な環境: Unix。

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

coroutine loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_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" が使われます。

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

   バージョン 3.5.3 で追加.

   バージョン 3.7 で変更: Added the *ssl_handshake_timeout* parameter.


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

coroutine 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" 例外を送
   出します。

   バージョン 3.7 で追加.


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

coroutine loop.start_tls(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_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" が使われます。

   バージョン 3.7 で追加.


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

loop.add_reader(fd, callback, *args)

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

   コールバック *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" オブジェクトとやりとりした方が便利なユースケースがい
くつかあります。

coroutine loop.sock_recv(sock, nbytes)

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

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

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

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

coroutine loop.sock_recv_into(sock, buf)

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

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

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

   バージョン 3.7 で追加.

coroutine loop.sock_sendall(sock, data)

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

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

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

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

coroutine 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()"。

coroutine 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()"。

coroutine 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* はノンブロッキングソケットでなければなりません。

   バージョン 3.7 で追加.


DNS
---

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

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

coroutine loop.getnameinfo(sockaddr, flags=0)

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

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


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

coroutine loop.connect_read_pipe(protocol_factory, pipe)

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

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

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

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

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

coroutine 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" を返します。

   利用可能な環境: Unix。

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


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

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

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

   引数 *executor* は "concurrent.futures.Executor" のインスタンスでな
   ければなりません。 *executor* が "None" の場合はデフォルトのエグゼ
   キュータが使われます。

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

      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)

      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)

   *executor* を "run_in_executor()" が使うデフォルトのエグゼキュータ
   に設定します。 *executor* は "ThreadPoolExecutor" のインスタンスで
   なければなりません。

   バージョン 3.8 で非推奨: "ThreadPoolExecutor" のインスタンスでない
   エグゼキュータの使用は非推奨となり、 Python 3.9 ではエラーになりま
   す。

   *executor* は "concurrent.futures.ThreadPoolExecutor" のインスタン
   スでなければなりません。


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

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

loop.set_exception_handler(handler)

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

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

loop.get_exception_handler()

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

   バージョン 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;

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

   注釈:

     このメソッドはイベントループの派生クラスでオーバーロードされては
     いけません。カスタム例外ハンドラの設定には
     "set_exception_handler()" メソッドを使ってください。


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

loop.get_debug()

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

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

loop.set_debug(enabled: bool)

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

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

参考: 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.

coroutine 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* は下記のいずれかをとることができます:

     * "connect_write_pipe()" メソッドを使ってサブプロセスの標準入力ス
       トリームに接続されたパイプを表す file-like オブジェクト

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

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

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

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

     * "connect_write_pipe()" メソッドを使ってサブプロセスの標準出力ス
       トリームに接続されたパイプを表す file-like オブジェクト

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

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

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

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

     * "connect_write_pipe()" メソッドを使ってサブプロセスの標準エラー
       出力ストリームに接続されたパイプを表す file-like オブジェクト

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

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

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

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

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

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

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

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

coroutine 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* によりインスタンス化されたオブジェ
   クトです。

注釈:

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


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

class asyncio.Handle

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

   cancel()

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

   cancelled()

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

      バージョン 3.7 で追加.

class asyncio.TimerHandle

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

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

   when()

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

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

      バージョン 3.7 で追加.


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

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

クラスを直接インスタンス化しないでください。

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 オブジェクトは非同
   期のコンテキストマネージャになりました。

   close()

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

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

      サーバーは非同期に停止されます。サーバーの停止を待ちたい場合は
      "wait_closed()" コルーチンを使用します。

   get_loop()

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

      バージョン 3.7 で追加.

   coroutine start_serving()

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

      このメソッドはべき等です。すなわちサーバがすでにサービスを開始し
      た後でも呼び出すことができます。

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

      バージョン 3.7 で追加.

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

      バージョン 3.7 で追加.

   is_serving()

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

      バージョン 3.7 で追加.

   coroutine wait_closed()

      "close()" メソッドが完了するまで待ちます。

   sockets

      サーバーがリッスンしている "socket.socket" オブジェクトのリスト
      です。

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


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

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

デフォルトでは、 asyncio は Unix では "SelectorEventLoop" 、 Windows
では "ProactorEventLoop" 、をそれぞれ使うように構成されています。

class asyncio.SelectorEventLoop

   "selectors" に基づくイベントループです。

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

      import asyncio
      import selectors

      class MyPolicy(asyncio.DefaultEventLoopPolicy):
         def new_event_loop(self):
            selector = selectors.SelectSelector()
            return asyncio.SelectorEventLoop(selector)

      asyncio.set_event_loop_policy(MyPolicy())

   Availability: Unix, Windows。

class asyncio.ProactorEventLoop

   "I/O 完了ポート" (IOCP) を使った Windows 向けのイベントループです。

   利用可能な環境: Windows 。

   参考: I/O 完了ポートに関する MSDN のドキュメント.

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.get_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.get_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.get_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 でのみ動きます。)

"loop.add_signal_handler()" メソッドを使用して "SIGINT" と "SIGTERM"
の2つのシグナルに対するハンドラを登録します:

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