asyncioは、Pythonで非同期I/Oを実現するためのライブラリで、複数のタスクを効率的に処理することができます。非同期プログラミングは、ネットワーク通信やファイル操作など、時間のかかるI/O操作を行う際に特に有用です。asyncioの基本的な使い方と具体的な例を紹介します。
asyncioの基本概念
イベントループ
asyncioの中心的なコンポーネントであり、非同期タスクのスケジューリングと実行を管理します。
コルーチン
async def
で定義される関数で、await
キーワードを使って他のコルーチンや非同期操作を待機します。
タスク
イベントループで実行されるコルーチンの実行単位です。
Future
非同期操作の結果を表すオブジェクトで、操作が完了するまで待機することができます。
asyncioの基本構文
import asyncio
async def main():
print("Hello")
await asyncio.sleep(1)
print("World")
# イベントループを取得して実行
asyncio.run(main())
この基本構文では、main
というコルーチンが定義され、asyncio.run
を使って実行されます。await asyncio.sleep(1)
で1秒間待機します。
例題1: 非同期タスクの実行
複数の非同期タスクを同時に実行する方法を示します。
import asyncio
async def task1():
print("Task 1: Start")
await asyncio.sleep(2)
print("Task 1: End")
async def task2():
print("Task 2: Start")
await asyncio.sleep(1)
print("Task 2: End")
async def main():
# 複数のタスクを同時に実行
await asyncio.gather(task1(), task2())
# イベントループを取得して実行
asyncio.run(main())
この例では、task1
とtask2
という2つの非同期タスクが同時に実行されます。task1
は2秒間待機し、task2
は1秒間待機します。
例題2: 非同期I/O操作
ファイルの非同期読み書きを行う方法を示します。
import asyncio
import aiofiles
async def write_file(filename, content):
async with aiofiles.open(filename, 'w') as f:
await f.write(content)
print(f"Written to {filename}")
async def read_file(filename):
async with aiofiles.open(filename, 'r') as f:
content = await f.read()
print(f"Read from {filename}: {content}")
async def main():
filename = 'example.txt'
content = 'Hello, asyncio!'
await write_file(filename, content)
await read_file(filename)
# イベントループを取得して実行
asyncio.run(main())
この例では、aiofiles
を使用してファイルの非同期読み書きを行います。write_file
コルーチンでファイルに書き込み、read_file
コルーチンでファイルを読み込みます。
例題3: 非同期ネットワーク通信
非同期でHTTPリクエストを送信する方法を示します。
import asyncio
import aiohttp
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
content = await response.text()
print(f"Read {len(content)} characters from {url}")
async def main():
urls = [
'https://www.example.com',
'https://www.python.org',
'https://www.github.com'
]
# 複数のURLに対して非同期リクエストを送信
tasks = [fetch(url) for url in urls]
await asyncio.gather(*tasks)
# イベントループを取得して実行
asyncio.run(main())
この例では、aiohttp
を使用して非同期でHTTPリクエストを送信し、複数のURLからコンテンツを取得します。
例題4: タスクのキャンセル
非同期タスクを途中でキャンセルする方法を示します。
import asyncio
async def long_running_task():
print("Task started")
try:
await asyncio.sleep(10)
except asyncio.CancelledError:
print("Task cancelled")
raise
print("Task completed")
async def main():
task = asyncio.create_task(long_running_task())
# 1秒待機してタスクをキャンセル
await asyncio.sleep(1)
task.cancel()
try:
await task
except asyncio.CancelledError:
print("Main: Task was cancelled")
# イベントループを取得して実行
asyncio.run(main())
この例では、long_running_task
というタスクを実行し、1秒後にそのタスクをキャンセルします。
結論
asyncioは、Pythonで非同期プログラミングを実現するための強力なライブラリです。asyncioを使用することで、I/O操作やネットワーク通信の効率が大幅に向上し、システムのパフォーマンスとスケーラビリティが改善されます。基本的な非同期タスクの実行からファイルの非同期読み書き、ネットワーク通信、タスクのキャンセルまで、asyncioの理解と適用は、Pythonプログラミングにおいて非常に有用です。