Open1
[Python3] 非同期処理 == 並行処理? await task1 や await task2 などと記述して処理の完了を待つ事にどんなメリットが有るのですか?
example.py
import asyncio
import time
async def async_sleep(sec):
print("task start")
await asyncio.sleep(sec)
print(f"waited time: {sec}s")
async def main():
print("start")
task1 = asyncio.create_task(async_sleep(2))
task2 = asyncio.create_task(async_sleep(4))
time.sleep(1)
print("sleep end")
await task1
task3 = asyncio.create_task(async_sleep(3))
await task2
await task3
asyncio.run(main())
非同期処理=並行処理?
はい、Pythonの非同期処理(asyncio)=並行処理です。
ただし「並列」ではなく「並行」(協調的に切り替えながら進む)です。
awaitで「完了を待つ」メリット
1. 順序制御ができる
- 例えば「task1が終わってからtask3を始めたい」場合、
await task1
で完了を待つことで、処理の順番を保証できます。
2. エラー処理がしやすい
-
await
した時点で、そのタスク内で発生した例外をキャッチできます。
これにより、個別のタスクの失敗を適切にハンドリングできます。
3. リソースの競合を防げる
- 例えば「ファイルをダウンロードしてから解析したい」など、依存関係がある処理では、
await
で順番を制御する必要があります。
すべて並行処理した方が効率的では?
依存関係がない場合は、その通りです。
すべてcreate_task
して、最後にawait asyncio.gather(task1, task2, task3)
のようにまとめて待つのが効率的です。
例:すべて並行でOKな場合
task1 = asyncio.create_task(async_sleep(2))
task2 = asyncio.create_task(async_sleep(4))
task3 = asyncio.create_task(async_sleep(3))
await asyncio.gather(task1, task2, task3)
この場合、3つのタスクが同時に進み、最も長いタスク(4秒)で全体が終わります。
まとめ
- awaitは「順番を制御したい」「エラーを個別に扱いたい」「依存関係がある」場合に有効
- 依存がなければ、すべて並行で進めて最後にまとめてawaitするのが効率的
状況に応じて使い分けるのがポイントです!