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

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

18.5.1。 ベースイベントループ

ソースコード: :source: `Lib / asyncio / events.py`

イベントループは、 asyncio によって提供される中央実行デバイスです。 次のような複数の機能を提供します。

  • 遅延呼び出し(タイムアウト)の登録、実行、およびキャンセル。
  • さまざまな種類の通信用のクライアントおよびサーバートランスポートを作成します。
  • 外部プログラムとの通信のためにサブプロセスと関連するトランスポートを起動します。
  • コストのかかる関数呼び出しをスレッドのプールに委任します。
class asyncio.BaseEventLoop
このクラスは実装の詳細です。 これは AbstractEventLoop のサブクラスであり、 asyncio にある具象イベントループ実装の基本クラスである可能性があります。 直接使用しないでください。 代わりに AbstractEventLoop を使用してください。 BaseEventLoopをサードパーティのコードでサブクラス化しないでください。 内部インターフェースが安定していません。
class asyncio.AbstractEventLoop

イベントループの抽象基本クラス。

このクラスはスレッドセーフではありません

18.5.1.1。 イベントループを実行する

AbstractEventLoop.run_forever()

stop()が呼び出されるまで実行します。 run_forever()が呼び出される前に stop()が呼び出された場合、これはタイムアウトゼロでI / Oセレクターを1回ポーリングし、I / Oイベントに応答してスケジュールされたすべてのコールバックを実行します(およびすでにスケジュールされているもの)、そして終了します。 run_forever()の実行中に stop()が呼び出されると、コールバックの現在のバッチが実行されて終了します。 その場合、コールバックによってスケジュールされたコールバックは実行されないことに注意してください。 次回 run_forever()が呼び出されたときに実行されます。

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

AbstractEventLoop.run_until_complete(future)

Future が完了するまで実行します。

引数がコルーチンオブジェクトの場合、 sure_future()でラップされます。

Futureの結果を返すか、その例外を発生させます。

AbstractEventLoop.is_running()
イベントループの実行ステータスを返します。
AbstractEventLoop.stop()

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

これにより、 run_forever()は次の適切な機会に終了します(詳細については、そこを参照してください)。

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

AbstractEventLoop.is_closed()

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

バージョン3.4.2の新機能。

AbstractEventLoop.close()

イベントループを閉じます。 ループが実行されていない必要があります。 保留中のコールバックは失われます。

これにより、キューがクリアされ、エグゼキュータがシャットダウンされますが、エグゼキュータが終了するのを待ちません。

これはべき等で不可逆的です。 この後、他のメソッドを呼び出すことはできません。


18.5.1.2。 呼び出し

ほとんどの asyncio 関数はキーワードを受け入れません。 コールバックにキーワードを渡したい場合は、 functools.partial()を使用してください。 たとえば、loop.call_soon(functools.partial(print, "Hello", flush=True))print("Hello", flush=True)を呼び出します。

ノート

functools.partial()は、lambda関数よりも優れています。これは、 asynciofunctools.partial()オブジェクトを検査して、デバッグモードでパラメーターを表示できるためです。 、一方、lambda関数の表現は不十分です。


AbstractEventLoop.call_soon(callback, \*args)

できるだけ早くコールバックが呼び出されるように手配します。 コールバックは、 call_soon()が戻った後、制御がイベントループに戻ったときに呼び出されます。

これは FIFO キューとして機能し、コールバックは登録された順序で呼び出されます。 各コールバックは1回だけ呼び出されます。

コールバック後の位置引数は、呼び出されたときにコールバックに渡されます。

asyncio.Handle のインスタンスが返されます。これは、コールバックをキャンセルするために使用できます。

functools.partialを使用して、キーワードをコールバックに渡します

AbstractEventLoop.call_soon_threadsafe(callback, \*args)

call_soon()と同様ですが、スレッドセーフです。

ドキュメントの同時実行およびマルチスレッドセクションを参照してください。


18.5.1.3。 遅延通話

イベントループには、タイムアウトを計算するための独自の内部クロックがあります。 どのクロックが使用されるかは、(プラットフォーム固有の)イベントループの実装によって異なります。 理想的には単調な時計です。 これは通常、 time.time()とは異なるクロックになります。

ノート

タイムアウト(相対遅延または絶対の場合)は1日を超えてはなりません。


AbstractEventLoop.call_later(delay, callback, *args)

指定された delay 秒(intまたはfloat)の後に callback が呼び出されるように調整します。

asyncio.Handle のインスタンスが返されます。これは、コールバックをキャンセルするために使用できます。

callback は、 call_later()への呼び出しごとに1回だけ呼び出されます。 2つのコールバックがまったく同時にスケジュールされている場合、どちらが最初に呼び出されるかは未定義です。

オプションの定位置 args は、呼び出されたときにコールバックに渡されます。 名前付き引数を使用してコールバックを呼び出す場合は、クロージャまたは functools.partial()を使用します。

functools.partialを使用して、キーワードをコールバックに渡します

AbstractEventLoop.call_at(when, callback, *args)

AbstractEventLoop.time()と同じ時間参照を使用して、コールバックが指定された絶対タイムスタンプ when (intまたはfloat)で呼び出されるように調整します。

このメソッドの動作は、 call_later()と同じです。

asyncio.Handle のインスタンスが返されます。これは、コールバックをキャンセルするために使用できます。

functools.partialを使用して、キーワードをコールバックに渡します

AbstractEventLoop.time()
イベントループの内部クロックに従って、現在の時刻を float 値として返します。

も参照してください

asyncio.sleep()機能。


18.5.1.4。 先物

AbstractEventLoop.create_future()

ループにアタッチされた asyncio.Future オブジェクトを作成します。

これは、asyncioでfutureを作成するための推奨される方法です。これは、イベントループの実装がFutureクラスの代替実装を提供できるためです(パフォーマンスまたはインストルメンテーションが向上します)。

バージョン3.5.2の新機能。


18.5.1.5。 タスク

AbstractEventLoop.create_task(coro)

コルーチンオブジェクトの実行をスケジュールします。将来的にラップします。 Task オブジェクトを返します。

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

このメソッドはPython3.4.2で追加されました。 async()関数を使用して、古いPythonバージョンもサポートします。

バージョン3.4.2の新機能。

AbstractEventLoop.set_task_factory(factory)

AbstractEventLoop.create_task()で使用されるタスクファクトリを設定します。

factoryNoneの場合、デフォルトのタスクファクトリが設定されます。

factorycallable の場合、(loop, coro)に一致する署名が必要です。ここで、 loop はアクティブなイベントループへの参照になります。 X157X] coro はコルーチンオブジェクトになります。 呼び出し可能オブジェクトは、 asyncio.Future 互換オブジェクトを返す必要があります。

バージョン3.4.4の新機能。

AbstractEventLoop.get_task_factory()

タスクファクトリを返すか、デフォルトのものが使用されている場合はNoneを返します。

バージョン3.4.4の新機能。


18.5.1.6。 接続の作成

18.5.1.7。 リスニング接続の作成

18.5.1.8。 ファイル記述子を監視する

SelectorEventLoop を使用するWindowsでは、ソケットハンドルのみがサポートされます(例:パイプファイル記述子はサポートされません)。

ProactorEventLoop を使用するWindowsでは、これらのメソッドはサポートされていません。

AbstractEventLoop.add_reader(fd, callback, \*args)

ファイル記述子の読み取り可能性の監視を開始してから、指定された引数を使用してコールバックを呼び出します。

functools.partialを使用して、キーワードをコールバックに渡します

AbstractEventLoop.remove_reader(fd)
読み取りの可用性についてファイル記述子の監視を停止します。
AbstractEventLoop.add_writer(fd, callback, \*args)

ファイル記述子の書き込み可能性の監視を開始してから、指定された引数を使用してコールバックを呼び出します。

functools.partialを使用して、キーワードをコールバックに渡します

AbstractEventLoop.remove_writer(fd)
書き込みの可用性についてファイル記述子の監視を停止します。

読み取りイベントのファイル記述子を監視するの例では、低レベルの AbstractEventLoop.add_reader()メソッドを使用してソケットのファイル記述子を登録します。


18.5.1.9。 低レベルのソケット操作

18.5.1.10。 ホスト名を解決する

18.5.1.11。 パイプを接続する

SelectorEventLoop を使用するWindowsでは、これらのメソッドはサポートされていません。 ProactorEventLoop を使用して、Windowsでパイプをサポートします。

も参照してください

AbstractEventLoop.subprocess_exec()およびAbstractEventLoop.subprocess_shell()メソッド。


18.5.1.12。 UNIXシグナル

可用性:UNIXのみ。

AbstractEventLoop.add_signal_handler(signum, callback, \*args)

シグナルのハンドラーを追加します。

シグナル番号が無効またはキャッチできない場合は、 ValueError を発生させます。 ハンドラーの設定に問題がある場合は、 RuntimeError を発生させます。

functools.partialを使用して、キーワードをコールバックに渡します

AbstractEventLoop.remove_signal_handler(sig)

シグナルのハンドラーを削除します。

シグナルハンドラが削除された場合はTrueを返し、削除されなかった場合はFalseを返します。

も参照してください

信号モジュール。


18.5.1.13。 エグゼキュータ

Executor (スレッドのプールまたはプロセスのプール)で関数を呼び出します。 デフォルトでは、イベントループはスレッドプールエグゼキューター( ThreadPoolExecutor )を使用します。

AbstractEventLoop.set_default_executor(executor)
run_in_executor()で使用されるデフォルトのエグゼキュータを設定します。


18.5.1.14。 エラー処理API

イベントループでの例外の処理方法をカスタマイズできます。

AbstractEventLoop.set_exception_handler(handler)

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

handlerNoneの場合、デフォルトの例外ハンドラーが設定されます。

handler が呼び出し可能なオブジェクトである場合、(loop, context)と一致する署名が必要です。ここで、loopはアクティブなイベントループcontextへの参照になります。 dictオブジェクトになります(コンテキストの詳細については、 call_exception_handler()のドキュメントを参照してください)。

AbstractEventLoop.get_exception_handler()

例外ハンドラーを返すか、デフォルトのハンドラーが使用されている場合はNoneを返します。

バージョン3.5.2の新機能。

AbstractEventLoop.default_exception_handler(context)

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

これは、例外が発生し、例外ハンドラーが設定されていない場合に呼び出され、デフォルトの動作を延期したいカスタム例外ハンドラーによって呼び出すことができます。

context パラメーターは、 call_exception_handler()と同じ意味です。

AbstractEventLoop.call_exception_handler(context)

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

context は、次のキーを含むdictオブジェクトです(新しいキーは後で導入される可能性があります)。

  • 'メッセージ':エラーメッセージ;

  • 'exception'(オプション):例外オブジェクト。

  • 'future'(オプション): asyncio.Future インスタンス;

  • 'handle'(オプション): asyncio.Handle インスタンス;

  • 'protocol'(オプション): Protocol インスタンス;

  • 'transport'(オプション): Transport インスタンス;

  • 'socket'(オプション): socket.socket インスタンス。

ノート

注:このメソッドは、サブクラス化されたイベントループでオーバーロードしないでください。 カスタム例外処理には、 set_exception_handler()メソッドを使用します。


18.5.1.15。 デバッグモード

AbstractEventLoop.get_debug()

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

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

バージョン3.4.2の新機能。

AbstractEventLoop.set_debug(enabled: bool)

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

バージョン3.4.2の新機能。

も参照してください

asyncio デバッグモード。


18.5.1.16。 サーバ

class asyncio.Server

ソケットでリッスンしているサーバー。

AbstractEventLoop.create_server()メソッドとstart_server()関数によって作成されたオブジェクト。 クラスを直接インスタンス化しないでください。

close()

提供を停止する:リスニングソケットを閉じ、 sockets 属性をNoneに設定します。

既存の着信クライアント接続を表すソケットは開いたままになります。

サーバーは非同期で閉じられます。wait_closed()コルーチンを使用して、サーバーが閉じられるまで待機します。

sockets

サーバーがリッスンしている socket.socket オブジェクトのリスト、またはサーバーが閉じている場合はNone


18.5.1.17。 取り持つ

class asyncio.Handle
AbstractEventLoop.call_soon()AbstractEventLoop.call_soon_threadsafe()AbstractEventLoop.call_later()、および AbstractEventLoop.call_atによって返されるコールバックラッパーオブジェクト)
cancel()
通話をキャンセルします。 コールバックがすでにキャンセルまたは実行されている場合、このメソッドは効果がありません。


18.5.1.18。 イベントループの例

18.5.1.18.1。 call_soon()を使用したHello World

AbstractEventLoop.call_soon()メソッドを使用してコールバックをスケジュールする例。 コールバックは"Hello World"を表示してから、イベントループを停止します。

import asyncio

def hello_world(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()
loop.run_forever()
loop.close()

も参照してください

Hello Worldコルーチンの例では、コルーチンを使用しています。


18.5.1.18.2。 call_later()で現在の日付を表示する

現在の日付を毎秒表示するコールバックの例。 コールバックは、 AbstractEventLoop.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()
loop.run_forever()
loop.close()

も参照してください

現在の日付を表示するコルーチンの例では、コルーチンを使用しています。


18.5.1.18.3。 読み取りイベントのファイル記述子を監視する

AbstractEventLoop.add_reader()メソッドを使用してファイル記述子がデータを受信するまで待ってから、イベントループを閉じます。

import asyncio
try:
    from socket import socketpair
except ImportError:
    from asyncio.windows_utils 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())

# Run the event loop
loop.run_forever()

# We are done, close sockets and the event loop
rsock.close()
wsock.close()
loop.close()

も参照してください

プロトコルを使用してデータを待機するために開いているソケットを登録するの例では、AbstractEventLoop.create_connection()メソッドによって作成された低レベルのプロトコルを使用します。

ストリームを使用してデータを待機するためのオープンソケットの登録の例では、コルーチンのopen_connection()関数によって作成された高レベルのストリームを使用します。


18.5.1.18.4。 SIGINTおよびSIGTERMのシグナルハンドラーを設定します

AbstractEventLoop.add_signal_handler()メソッドを使用して、シグナルSIGINTおよびSIGTERMのハンドラーを登録します。

import asyncio
import functools
import os
import signal

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

loop = asyncio.get_event_loop()
for signame in ('SIGINT', 'SIGTERM'):
    loop.add_signal_handler(getattr(signal, signame),
                            functools.partial(ask_exit, signame))

print("Event loop running forever, press Ctrl+C to interrupt.")
print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())
try:
    loop.run_forever()
finally:
    loop.close()

この例はUNIXでのみ機能します。