LoginSignup
0
0

#0019 async/awaitの触り

Last updated at Posted at 2023-08-21

はじめに

  • 最近非同期処理について触れることがあり、pythonのasync/awaitについて調べてみた。
  • 深掘ろうとすると、抜けなくなりそうなので、簡単な実装で終える。

非同期処理とは

  • 処理Aと処理Bを同時に実行できる
  • 並行処理
  • 同期処理(逐次処理)の逆の意味の言葉
  • 非同期処理を使う場面は、「処理の完了まで時間がかかる」場合
  • pythonではI/Oバウンド(入出力における負荷)の軽減ために用いられる。
    • ファイルの読み書き
    • DBの読み書き

asyncio 非同期I/O

asyncio は async/await 構文を使い 並行処理の コードを書くためのライブラリです。

asyncio は、高性能なネットワークとウェブサーバ、データベース接続ライブラリ、分散タスクキューなどの複数の非同期 Python フレームワークの基盤として使われています

公式ref

asyncioを使った実装1

まず使ってみる。(非同期処理ではない)

import asyncio
import time

async def main():
    print(f"Start : {time.strftime('%X')}")
    await asyncio.sleep(3)
    print(f"Rest  : {time.strftime('%X')}")
    await asyncio.sleep(1)
    print(f"End   : {time.strftime('%X')}")

if __name__ == "__main__":
    asyncio.run(main())

❯❯❯ python async_test.py
Start : 22:51:19
Rest  : 22:51:22
End   : 22:51:23  #合計6秒なので、これは同期処理。

(memo) コルーチン(asynicをつける)にawaitをつけるとコルーチンが実行されて処理が終わるまで待つになる。

関数を使って実装してみる。

async def function(wait_sec):
    await asyncio.sleep(wait_sec)
    return f"Wait for {wait_sec} sec."

async def main():
    print(f"Start : {time.strftime('%X')}")
    results_1 = await function(2)
    print(results_1)
    print(f"Rest  : {time.strftime('%X')}")
    results_2 = await function(4)
    print(results_2)
    print(f"End   : {time.strftime('%X')}")

if __name__ == "__main__":
    asyncio.run(main())

❯❯❯ python async_test.py
Start : 22:59:52
Wait for 2 sec.
Rest  : 22:59:54
Wait for 4 sec.
End   : 22:59:58 #合計6秒なので、これは同期処理。

(memo) コルーチンの処理を関数として切り出したら、関数の前にawaitをつける必要がある。(なんか変な感じだ...)

asyncioを使った実装2

非同期処理を実装する。async.create_taskを利用する。

async def main():
    print(f"Start : {time.strftime('%X')}")
    task1 = asyncio.create_task(function(2))
    task2 = asyncio.create_task(function(4))
    await task1
    await task2
    print(task1.result())
    print(task2.result())
    print(f"End   : {time.strftime('%X')}")


if __name__ == "__main__":
    asyncio.run(main())

❯❯❯ python async_test.py
Start : 23:05:09
Wait for 2 sec.
Wait for 4 sec.
End   : 23:05:13  #合計4秒なので、これは非同期処理!!

できた。

おわりに

  • 非同期処理の奥は深く、gather, await future, await coroutine, run_in_executor, wait_forなど、扱えたら扱いたい。
  • コルーチン とは  「いったん処理を中断した後、続きから処理を再開できるプログラミングの構造。」

コルーチン(英: co-routine)とはプログラミングの構造の一種。サブルーチンがエントリーからリターンまでを一つの処理単位とするのに対し、コルーチンはいったん処理を中断した後、続きから処理を再開できる。接頭辞 co は協調を意味するが、複数のコルーチンが中断・継続により協調動作を行うことによる。
サブルーチンと異なり、状態管理を意識せずに行えるため、協調的処理、イテレータ、無限リスト、パイプなど、継続状況を持つプログラムが容易に記述できる。

(参考wiki)

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