- AsyncioはPythonでI/Oバウンドなプログラムを扱う優れた方法であり、基本的にPythonのGeneratorの上に優れたレイヤーを提供する
- Generatorはコードをメモリ効率良くし、
yieldキーワードを使って関数を一時停止・再開できる
yield fromを使うと、generatorがsub-generatorやiterableオブジェクトを呼び出せるため、generatorチェーンを作れる
イベントループ
- Asyncioの中核は、現在のtaskを実行・管理するevent loopである
- Event loopはtaskの一覧を反復しながら、
next(task)で各taskを実行する
- TaskはI/O処理中に
yieldを使って実行を一時停止し、制御をevent loopに返す
スリープ
yield fromを使ってtaskにsub-generatorを追加できる
- Sleep generatorを追加すると、指定した時間までtaskの実行を一時停止できる
- Sleepが
whileループを抜けるとStopIteration例外が発生し、task関数のyield fromは次のコード行へ進む
YieldからAwaitへ
__await__ダンダーメソッドとasyncキーワードを使って、yieldからawaitへ移行できる
awaitキーワードはクラスインスタンスの__await__メソッドを呼び出すか、コルーチン(async関数で生成されたオブジェクト)で使用できる
awaitキーワードはyield fromの同義語と見なせ、少し追加の妥当性チェック規則がある
- 独自の
Taskクラスを作って__await__メソッドを実装し、create_task関数で生成したtaskをイベントループに追加する
- イベントループ管理者はtaskを実行し、
StopIteration例外が発生したらtaskを完了として処理する
- Sleep関数もasync互換になるように修正する必要がある
AsyncIOとAwait
- 上のコードで"jacobio"を"asyncio"に置き換えると、asyncioパッケージを完全に使うことになる
- Asyncioはさらに多くの処理を行うが、基本的なgeneratorからasyncioの中核部分をゼロから再現できる
- 実際のasyncioパッケージでは、
asyncio.gather()のような関数を使って複数のtaskを処理できる
GN⁺の見解
- この記事はasyncioの動作原理をgeneratorを使ってわかりやすく説明しており、asyncioに初めて触れる開発者に大いに役立ちそうだ
- Asyncioは高性能なI/O処理に最適化されたライブラリであり、この記事を通じてその内部構造を理解すれば、実際のプロジェクトでより効果的に活用できるだろう
- ただし実際のasyncioははるかに複雑な構造を持つため、実務で使うには公式ドキュメントなどを通じたより深い学習が必要だと思われる
- Asyncioと似た機能を提供する他のライブラリとしてはTrioやCurioなどがあり、それらとの違いを比較してみるのも興味深いだろう
- Asyncioを導入する際は、既存の同期コードとの互換性、エラー処理、テストなど考慮すべき点が多いため、十分な検討と準備が必要だろう
まだコメントはありません。