LoginSignup
0
3

More than 3 years have passed since last update.

asyncio を使って非同期処理をしてみた

Posted at

きっかけ

asyncioの良さげなサンプルコードがなかったのですが、Python でのオンデマンド・データ, 第 3 回 コルーチンと asyncioがレストランにいるウェイターが複数のオーダーに対応するといったより具体的なストーリーを交えて説明していたので一番分かりやすくて参考になります。
よく見かけるpython3 の async/awaitを理解するPythonにおける非同期処理: asyncio逆引きリファレンスよりも良いです。

開発

import asyncio
import time

async def start_time(src):
    await asyncio.sleep(src)
    print("START!!!")

async def main_process(span):
    idx = 1
    while True:
        await asyncio.sleep(span)
        num_active_tasks = len([ task for task in asyncio.Task.all_tasks(loop) if not task.done()])
        if num_active_tasks == 1:
            break
        print("[run:{}]{}秒経過".format(num_active_tasks, idx * span))
        idx += 1


async def end_time(src):
    await asyncio.sleep(src)
    print("END!!!")

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(
            asyncio.gather(
                start_time(10),
                main_process(1),
                end_time(20)
            )
        )
    finally:
        loop.close()

注目点は
len([ task for task in asyncio.Task.all_tasks(loop) if not task.done()])
asyncio.Task.all_tasks(loop) if not task.done() とすることで現在常駐しているタスクを取得することができます。

結果

出力結果は下記の通りです。
メイン処理のみ起動している場合はloopから抜けています。

[run:3]1秒経過
[run:3]2秒経過
[run:3]3秒経過
[run:3]4秒経過
[run:3]5秒経過
[run:3]6秒経過
[run:3]7秒経過
[run:3]8秒経過
[run:3]9秒経過
START!!!
[run:2]10秒経過
[run:2]11秒経過
[run:2]12秒経過
[run:2]13秒経過
[run:2]14秒経過
[run:2]15秒経過
[run:2]16秒経過
[run:2]17秒経過
[run:2]18秒経過
[run:2]19秒経過
END!!!

おわりに

asyncio.Task.all_tasks() ですが Python3.7 以降では非推奨で3.9では削除されるとのことです。特にasyncioの部分でversionが上がるごとに書き方がかなり様変わりしそうです。
(Python3.8 doc Task オブジェクト を参照)

参考したリンク

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3