PEP 0492async
キーワードをPython 3.5に追加します。
Pythonこの演算子を使用するとどのようにメリットがありますか?コルーチンの例は次のとおりです。
async def read_data(db):
data = await db.fetch('SELECT ...')
ドキュメントによると、これは達成します
db.fetch awaitableが完了して結果データを返すまで、read_dataコルーチンの実行を一時停止します。
このasync
キーワードには、実際には新しいスレッドの作成が含まれますか、それとも既存の予約済み非同期スレッドの使用が含まれますか?
async
が予約済みスレッドを使用する場合、それはそれぞれ独自の単一の共有スレッドですか?
いいえ、コルーチンにはいかなる種類のスレッドも含まれていません。コルーチンは、cooperativeマルチタスクを可能にし、各コルーチンが自発的に制御を生成します。一方、スレッドは任意のポイントでユニットを切り替えます。
Python 3.4までは、generators;を使用して、yield
またはyield from
式を使用してコルーチンを記述できました。代わりにジェネレーターオブジェクトを作成する関数本体。コードはジェネレーターを反復処理したときにのみ実行されます。追加のイベントループライブラリ( asyncio
など)と一緒に、次の信号を送るコルーチンを記述できます。彼らが忙しくなり(おそらくI/Oを待っている)、その間に別のコルーチンを実行できるというイベントループ:
import asyncio
import datetime
@asyncio.coroutine
def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(1)
上記のコードがyield from asyncio.sleep(1)
行に進むたびに、このルーチンは次の1秒間は何も実行しないため、イベントループは別のコルーチンを自由に実行できますとにかく。
ジェネレーターはコルーチンだけでなくあらゆる種類のタスクに使用でき、ジェネレーター構文を使用してコルーチンを作成すると初心者が混乱する可能性があるため、PEPはそれを実現する新しい構文を導入しますコルーチンを書いていることをより明確に。
PEPを実装すると、上記のサンプルは代わりに次のように記述できます。
async def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(1)
結果のcoroutine
オブジェクトには、コルーチンを駆動するためのイベントループが必要です。イベントループは、各コルーチンで順番にawait
し、何かを完了するために現在await
していないコルーチンを実行します。
利点は、ネイティブサポートを使用して、非同期コンテキストマネージャーとイテレーターをサポートするための追加の構文を導入できることです。コンテキストマネージャーの開始と終了、またはイテレーターのループは、コルーチン内のより多くのポイントになり、何かが再び待機しているために他のコードを代わりに実行できることを示します。