Edited at

Python3での非同期処理まとめ

More than 1 year has passed since last update.


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

https://docs.python.org/3/library/asyncio-task.html#example-chain-coroutines


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))

https://docs.python.org/3/library/asyncio-task.html#example-parallel-execution-of-tasks