-
Python3.5から、非同期処理がデフォルトで利用できます。
- 完結にまとめしたくて書きました。
- https://docs.python.org/3/library/asyncio-task.html
-
async処理の考えかたやメリットはここ
1.シンプルなパターン
import asyncio
# 時間がかかる処理を含む関数
async def compute(x, y):
print("Compute %s + %s ..." % (x, y))
# 時間がかかる処理にはawaitつける
await asyncio.sleep(1.0)
return x + y
async def print_sum(x, y):
result = await compute(x, y)
print("%s + %s = %s" % (x, y, result))
loop = asyncio.get_event_loop()
# async関数の実行
loop.run_until_complete(print_sum(1, 2))
結果
Compute 1 + 2 ...
1 + 2 = 3
2.並列で実行するパターン
import asyncio
# 時間がかかる処理を含む関数
async def factorial(name, number):
f = 1
for i in range(2, number+1):
print("Task %s: Compute factorial(%s)..." % (name, i))
await asyncio.sleep(1)
f *= i
print("Task %s: factorial(%s) = %s" % (name, number, f))
loop = asyncio.get_event_loop()
# 並列で実行 -> tupleで返す
result = loop.run_until_complete(asyncio.gather(
factorial("A", 2),
factorial("B", 3),
factorial("C", 4),
))
結果
Task C: Compute factorial(2)...
Task B: Compute factorial(2)...
Task A: Compute factorial(2)...
Task C: Compute factorial(3)...
Task B: Compute factorial(3)...
Task A: factorial(2) = 2
Task C: Compute factorial(4)...
Task B: factorial(3) = 6
Task C: factorial(4) = 24
TaskA,B,Cが並列で実行されていることがわかる。
3.ちょっと綺麗に
gatherの中を綺麗に表現するためには以下のようにできる。やっていることは2と全く同じ
loop = asyncio.get_event_loop()
name_number_list = [("A",2),("B", 3),("C", 4)]
parallel_tasks = tuple(map(lambda name_num: factorial(*name_num), name_number_list))
result = loop.run_until_complete(asyncio.gather(*parallel_tasks))