イベントループ¶
ソースコード: 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.12 で非推奨: Deprecation warning is emitted if there is no current event loop. 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 を持っています:
ループの開始と停止¶
- loop.run_until_complete(future)¶
フューチャー (
Future
インスタンス) が完了するまで実行します。引数が コルーチンオブジェクト の場合、暗黙のうちに
asyncio.Task
として実行されるようにスケジュールされます。Future の結果を返すか、例外を送出します。
- loop.run_forever()¶
stop()
が呼び出されるまでイベントループを実行します。If
stop()
is called beforerun_forever()
is called, the loop will poll the I/O selector once with a timeout of zero, run all callbacks scheduled in response to I/O events (and those that were already scheduled), and then exit.run_forever()
メソッドを実行中にstop()
メソッドが呼び出された場合、イベントループは現在処理されているすべてのコールバックを実行してから終了します。 この場合、コールバックにより新たにスケジュールされるコールバックは実行されないことに注意してください; これら新たにスケジュールされたコールバックは、次にrun_forever()
またはrun_until_complete()
が呼び出されたときに実行されます。
- loop.stop()¶
イベントループを停止します。
- loop.is_running()¶
イベントループが現在実行中の場合
True
を返します。
- loop.is_closed()¶
イベントループが閉じられていた場合
True
を返します。
- loop.close()¶
イベントループをクローズします。
この関数が呼び出される時点で、イベントループが実行中であってはいけません。保留中のコールバックはすべて破棄されます。
このメソッドは全てのキューをクリアし、エグゼキューターが実行完了するのを待たずにシャットダウンします。
このメソッドはべき等 (何回実行しても結果は同じ) であり取り消せません。イベントループがクローズされた後、他のいかなるメソッドも呼び出すべきではありません。
- coroutine loop.shutdown_asyncgens()¶
Schedule all currently open asynchronous generator objects to close with an
aclose()
call. After calling this method, the event loop will issue a warning if a new asynchronous generator is iterated. This should be used to reliably finalize all scheduled asynchronous generators.asyncio.run()
を使った場合はこの関数を呼び出す必要はありません。以下はプログラム例です:
try: loop.run_forever() finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()
Added in version 3.6.
- coroutine 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 withloop.run_in_executor()
will raise aRuntimeError
.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 で変更: Added the timeout parameter.
コールバックのスケジューリング¶
- 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, sincecall_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 で修正されました。
注釈
バージョン 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)¶
Schedule the execution of coroutine coro. Return a
Task
object.サードパーティのイベントループは相互運用のための自身の
Task
のサブクラスを使用できます。この場合、結果はTask
のサブクラスになります。name 引数が指定され、値が
None
でない場合、Task.set_name()
メソッドにより name がタスクの名前として設定されます。省略可能なキーワード引数 context によって、coro を実行するためのカスタムの
contextvars.Context
を指定できます。context が省略された場合、現在のコンテキストのコピーが作成されます。バージョン 3.8 で変更: name パラメータを追加しました。
バージョン 3.11 で変更: context パラメータを追加しました。
- 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, context=None)
, where loop is a reference to the active event loop, and coro is a coroutine object. The callable must return aasyncio.Future
-compatible object.
- 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, ssl_shutdown_timeout=None, happy_eyeballs_delay=None, interleave=None, all_errors=False)¶
host と port で指定されたアドレスとのストリーミングトランスポート接続をオープンします。
The socket family can be either
AF_INET
orAF_INET6
depending on host (or the family argument, if provided).The socket type will be
SOCK_STREAM
.protocol_factory は asyncio プロトコル の実装を返す呼び出し可能オブジェクトでなければなりません。
このメソッドはバックグラウンドで接続の確立を試みます。成功した場合、メソッドは
(transport, protocol)
のペアを返します。時系列での下層処理の概要は以下のとおりです:
接続を確立し、その接続に対する トランスポート が生成されます。
protocol_factory が引数なしで呼び出され、ファクトリが プロトコル インスタンスを返すよう要求します。
プロトコルインスタンスが
connection_made()
メソッドを呼び出すことにより、トランスポートと紐付けられます。成功すると
(transport, protocol)
タプルが返されます。
作成されたトランスポートは実装依存の双方向ストリームです。
その他の引数:
ssl: 偽値以外が与えられた場合、SSL/TLS トランスポートが作成されます (デフォルトでは暗号化なしの TCP トランスポートが作成されます)。 ssl が
ssl.SSLContext
オブジェクトの場合、このコンテキストがトランスポートを作成するために使用されます; ssl がTrue
の場合、ssl.create_default_context()
が返すデフォルトのコンテキストが使われます。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 ifNone
(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 singleOSError
with the error messages combined. Whenall_errors
isTrue
, anExceptionGroup
will be raised containing all exceptions (even if there is only one).
バージョン 3.5 で変更:
ProactorEventLoop
において SSL/TLS のサポートが追加されました。バージョン 3.6 で変更: The socket option socket.TCP_NODELAY is set by default for all TCP connections.
バージョン 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.
For more information: https://datatracker.ietf.org/doc/html/rfc6555
バージョン 3.11 で変更: ssl_shutdown_timeout パラメータが追加されました。
バージョン 3.12 で変更: all_errors が追加されました
参考
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_port=None, allow_broadcast=None, sock=None)¶
データグラム接続 (UDP) を生成します。
The socket family can be either
AF_INET
,AF_INET6
, orAF_UNIX
, depending on host (or the family argument, if provided).The socket type will be
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 tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows and some Unixes. If the socket.SO_REUSEPORT constant is not defined then this capability is unsupported.
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 で変更: The family, proto, flags, reuse_address, reuse_port, allow_broadcast, and sock parameters were added.
バージョン 3.8 で変更: Windows サポートが追加されました。
バージョン 3.8.1 で変更: The reuse_address parameter is no longer supported, as using socket.SO_REUSEADDR poses a significant security concern for UDP. Explicitly passing
reuse_address=True
will raise an exception.SO_REUSEADDR
を使って、同一の UDP ソケットアドレスに対して複数のプロセスが異なる UID でソケットを割り当てている場合、受信パケットは複数のソケット間にランダムに分散する可能性があります。For supported platforms, reuse_port can be used as a replacement for similar functionality. With reuse_port, socket.SO_REUSEPORT is used instead, which specifically prevents processes with differing UIDs from assigning sockets to the same socket address.
バージョン 3.11 で変更: The reuse_address parameter, disabled since Python 3.8.1, 3.7.6 and 3.6.10, has been entirely removed.
- coroutine loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)¶
Unix 接続を生成します。
The socket family will be
AF_UNIX
; socket type will beSOCK_STREAM
.成功すると
(transport, protocol)
タプルが返されます。path は Unix ドメインソケット名で、 sock パラメータが指定されない場合は必須です。 抽象 Unix ソケット、
str
、bytes
、 andPath
形式でのパスがサポートされています。このメソッドの引数についての詳細は
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 パラメータが追加されました。
ネットワークサーバの生成¶
- 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, 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
orNone
(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
orAF_INET6
to force the socket to use IPv4 or IPv6. If not set, the family will be determined from host name (defaults toAF_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
が使われます。ssl_shutdown_timeout is the time in seconds to wait for the SSL shutdown to complete before aborting the connection.
30.0
seconds ifNone
(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 コードから使うことができます。
- coroutine 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)¶
Similar to
loop.create_server()
but works with theAF_UNIX
socket family.path は Unix ドメインソケット名で、 sock パラメータが指定されない場合は必須です。 抽象 Unix ソケット、
str
、bytes
、 andPath
形式でのパスがサポートされています。このメソッドの引数についての詳細は
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 パラメータが追加されました。
- coroutine 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 ifNone
(default).
(transport, protocol)
のペアを返します。Added in version 3.5.3.
バージョン 3.7 で変更: Added the ssl_handshake_timeout parameter.
バージョン 3.11 で変更: ssl_shutdown_timeout パラメータが追加されました。
ファイルの転送¶
- 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
例外を送出します。Added in version 3.7.
TLS へのアップグレード¶
- coroutine 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 ifNone
(default).
Added in version 3.7.
バージョン 3.11 で変更: ssl_shutdown_timeout パラメータが追加されました。
ファイル記述子の監視¶
- 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 はノンブロッキングソケットでなければなりません。
Added in version 3.7.
- coroutine 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.
- coroutine 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.
- 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_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.
- coroutine loop.sock_connect(sock, address)¶
ソケット sock をアドレス address のリモートソケットに接続します。
socket.connect()
の非同期版です。sock はノンブロッキングソケットでなければなりません。
バージョン 3.5.2 で変更:
address
を名前解決する必要はなくなりました。sock_connect
はsocket.inet_pton()
を呼び出して address が解決済みかどうかを確認します。未解決の場合、 address の名前解決にはloop.getaddrinfo()
メソッドが使われます。
- coroutine loop.sock_accept(sock)¶
接続を受け付けます。ブロッキングコールの
socket.accept()
メソッドをモデルとしています。ソケットはアドレスに束縛済みで、接続を listen 中である必要があります。戻り値は
(conn, address)
のペアで、conn は接続を通じてデータの送受信を行うための 新しい ソケットオブジェクト、address は接続先の端点でソケットに束縛されているアドレスを示します。sock はノンブロッキングソケットでなければなりません。
バージョン 3.7 で変更: このメソッドは常にコルーチンメソッドとしてドキュメントに記載されてきましたが、 Python 3.7 以前のリリースでは
Future
オブジェクトを返していました。 Python 3.7 からはasync def
メソッドになりました。参考
- 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 はノンブロッキングソケットでなければなりません。
Added in version 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()
の非同期版です。
注釈
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 からはどちらのメソッドもコルーチンになりました。
パイプとやりとりする¶
- 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
を使ってください。
参考
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 isNone
. The default executor can be set byloop.set_default_executor()
, otherwise, aconcurrent.futures.ThreadPoolExecutor
will be lazy-initialized and used byrun_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) if __name__ == '__main__': asyncio.run(main())
Note that the entry point guard (
if __name__ == '__main__'
) is required for option 3 due to the peculiarities ofmultiprocessing
, which is used byProcessPoolExecutor
. 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 ofThreadPoolExecutor
.バージョン 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
orHandle
, it is run in thecontextvars.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;- '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.
参考
サブプロセスの実行¶
この節で解説しているのは低水準のメソッドです。通常の 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 は下記のいずれかをとることができます:
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()
orconnect_read_pipe()
for use with the event loop.他の引数についての詳細は
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()
が返すコールバックのラッパーです。- 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()
, andloop.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).
- get_loop()¶
サーバオブジェクトに付随するイベントループを返します。
Added in version 3.7.
- coroutine 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.
- 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))
Added in version 3.7.
- is_serving()¶
サーバーが新規に接続の受け入れを開始した場合
True
を返します。Added in version 3.7.
- coroutine 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 SelectorEventLoop
on Unix and ProactorEventLoop
on Windows.
- class asyncio.SelectorEventLoop¶
An event loop based on the
selectors
module.プラットフォーム上で利用可能な最も効率の良い 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¶
An event loop for Windows that uses "I/O Completion Ports" (IOCP).
Availability: Windows.
- 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()
読み込みイベント用ファイル記述子の監視¶
ファイル記述子が 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())