asyncio 理解した気になる方法メモ
python の asyncio について。 きっちり理解した方がいいんだろうけどとりあえずお手軽に理解した気になれると(困らない限り)便利なので書いておく。
基本コード
関数 funcA()
と funcB()
を非同期に実行する。
前者は2秒間隔で A1
~ A3
を出力、後者は1秒間隔で B1
~ B5
を出力する。
実行コード
import time import asyncio from datetime import datetime, timedelta from typing import Callable async def funcA(current_fn: Callable): print(current_fn(), 'A1') await asyncio.sleep(2) print(current_fn(), 'A2') await asyncio.sleep(2) print(current_fn(), 'A3') async def funcB(current_fn: Callable): print(current_fn(), 'B1') await asyncio.sleep(1) print(current_fn(), 'B2') await asyncio.sleep(1) print(current_fn(), 'B3') await asyncio.sleep(1) print(current_fn(), 'B4') await asyncio.sleep(1) print(current_fn(), 'B5') async def main(): s = int(datetime.now().strftime('%S')) def current() -> str: t = datetime.now() + timedelta(seconds=(60-s)) return t.strftime('%S (%f)') await asyncio.gather( funcA(current), funcB(current), ) if __name__ == '__main__': asyncio.run(main())
以下すべて python3.8.10 で試した。
1)全部 asyncio.sleep()
こんな感じの出力になる(カッコ内はマイクロ秒):
00 (851502) A1 00 (851523) B1 01 (853204) B2 02 (852528) A2 02 (853741) B3 03 (855156) B4 04 (854765) A3 04 (856003) B5
たぶんイメージはこんな感じ:
await
してる間は別の処理ができる、という認識でよさそう?
(ちなみに B1
~ B2
間を time.sleep()
にしても同じ結果)
2)A2
~ A3
間を time.sleep()
にする
async def funcA(current_fn: Callable): print(current_fn(), 'A1') await asyncio.sleep(2) print(current_fn(), 'A2') - await asyncio.sleep(2) + time.sleep(2) print(current_fn(), 'A3')
出力はこうなる:
00 (961069) A1 00 (961089) B1 01 (962646) B2 02 (963158) A2 04 (965308) A3 04 (965432) B3 05 (966404) B4 06 (967694) B5
イメージ:
A2
~ A3
間は他の処理がブロックされる。
3)B2
~ B3
間を time.sleep()
にする
async def funcB(current_fn: Callable): print(current_fn(), 'B1') await asyncio.sleep(1) print(current_fn(), 'B2') - await asyncio.sleep(1) + time.sleep(1) print(current_fn(), 'B3') await asyncio.sleep(1) print(current_fn(), 'B4') await asyncio.sleep(1) print(current_fn(), 'B5')
出力:
00 (949751) A1 00 (949771) B1 01 (951187) B2 02 (952380) B3 02 (952671) A2 03 (953892) B4 04 (954185) A3 04 (954274) B5
ここまでの感じのイメージだと:
となって B5
の後に A3
が出力される気がするが、実際に試すと A3
が先になる。
これは B3
~ B5
間の処理のオーバーヘッドが B3
→ A2
の間隔より大きくなってしまう、みたいな理解でいいんだろうか。