[Python] 19. 非同期IOのasync/await(asyncio)を使う方法
こんにちは。明月です。
この投稿はPythonで非同期IOのasync/await(asyncio)を使う方法に関する説明です。
Threadで関数を実行する時にその結果を受け取ることが難しいです。
link - [Python] 17. スレッド(Thread)とロック(lock)、そしてデッドロック(deadlock)
つまり様々な制御文を並列で処理して結果をすべて待たなければならないです。
# スレッドとスレッド停止するモジュール
import threading, time
# 結果の変数
ret = 0
def example():
# グローバル変数を使用
global ret
# 1から9まで繰り返す。
for i in range(1,10,1):
# 0.1秒待つ
time.sleep(0.1)
# 変数を増加
ret += i
# example関数をスレッドで開始する。
th1 = threading.Thread(target=example)
th2 = threading.Thread(target=example)
# スレッド開始
th1.start()
th2.start()
# スレッドが終了する時まで待つ。
th1.join()
th2.join()
# 結果出力
print(ret)
上みたいにfor文を二つのスレッドに実行して計算することができます。でも、何かソースが複雑みたいです。
グローバル変数でretを生成して各スレッドでデータを入力、修正します。もし各スレッドでパラメータによってデータを変わることにしようと思うとすごく複雑になります。
でも非同期処理(async/await(asyncio))を使うと簡単に処理することができます。
# async/awaitを使うためのモジュール
import asyncio
# 関数の前にasync宣言して非同期を指定した。
async def example():
# 変数宣言
ret = 0
# 1から9まで繰り返す。
for i in range(1,10,1):
# 非同期処理 0.1を待機
await asyncio.sleep(0.1)
# 変数を増加
ret += i
# 結果を返却
return ret
# 非同期を使うためにはasync関数で実行する。
async def main():
# example関数を開始
t1 = asyncio.create_task(example())
t2 = asyncio.create_task(example())
# t1とt2が終了すれば結果値を出してコンソールに出力
print(await t1 + await t2)
#async defを実行するための関数。
asyncio.run(main())
asyncとawaitを使えばthreadingを使う時よりソースを綺麗に作成することができます。
まず、asyncとは関数の前に使うキーワードです。外部では非同期を実行するためのキーワードだし、内部的にはawaitを使えるような予約語です。
main関数でt1とt2を待つawaitを使いましたが、もしmainがasyncではないしグローバル領域でawaitキーワードを使うとエラーが発生することになります。
awaitキーワードは非同期で待機する意味で、await asyncio.sleep(i)の場合はiを秒単位です待機する意味です。つまりtime.sleepと同じ意味です。
create_task担っているtaskオブジェクトからawaitを使えばスレッドが終了する時まで待機するthread.joinと同じ意味です。
最後にasyncio.runはasyncをcreate_taskみたいに非同期ではなく同期(プロセスの順番とおりに処理)で処理する呼び出しです。
asyncio.runを使ってもよいです。でも最近はrun_until_completeを使うことをお勧めしています。
またcreate_taskで非同期に分けましたが、asyncio.gatherも非同期処理が可能です。
# async/awaitを使うためのライブラリ
import asyncio
# 非同期を指定された関数
async def example():
# 変数設定
ret = 0
# 1から9まで繰り返す。
for i in range(1,10,1):
# 非同期処理 0.1を待機
await asyncio.sleep(0.1)
# 変数を増加
ret += i
# 結果を返却
return ret
# 非同期を使うためにはasync関数で実行する。
async def main():
# example関数を非同期で開始する。パラメータに関数を二つ入れることで非同期を二回に実行することと同じ意味。
ret = await asyncio.gather(example(), example())
# コンソール出力
print(sum(ret))
#async defを実行するような関数。
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
# 非同期を待つ。
loop.run_until_complete(main())
finally:
loop.close()
asyncio.set_event_loop(None)
link - https://docs.python.org/3/library/asyncio-task.html
link - https://docs.python.org/3/library/asyncio-eventloop.html
link - https://stackoverflow.com/questions/55590343/asyncio-run-or-run-until-complete
ここまでPythonで非同期IOのasync/await(asyncio)を使う方法に関する説明でした。
ご不明なところや間違いところがあればコメントしてください。
- [Python] 21. データベース(mariaDB)を連結する方法2020/06/24 18:51:50
- [Python] 20. stringフォマード(Formatting)と補間法(interpolation)2020/06/23 19:03:21
- [Python] 19. 非同期IOのasync/await(asyncio)を使う方法2020/06/22 18:10:12
- [Python] 18. ネットワーク(Socket)通信する方法2020/06/18 19:53:56
- [Python] 17. スレッド(Thread)とロック(lock)、そしてデッドロック(deadlock)2020/06/18 00:19:45
- [Python] 16. IO(ファイル読み取り、書き込み)を扱う方法2020/06/16 18:37:00
- [Python] 15. クラスを継承する方法2020/06/15 18:20:07
- [Python] 14. クラスプロパティ(Property)2020/06/12 17:45:13
- [Python] 13. クラス関数(class method)とダック・タイピング、そして特殊メソッド2020/06/11 19:42:29
- [Python] 12. クラス(Class)を使う方法2020/06/10 19:33:33
- check2024/04/10 19:03:53
- [Java] 64.Spring bootとReactを連結する方法(Buildする方法)2022/03/25 21:02:18
- [Javascript] Node.jsをインストールしてReactを使う方法2022/03/23 18:01:34
- [Java] 63. Spring bootでcronスケジューラとComponentアノテーション2022/03/16 18:57:30
- [Java] 62. Spring bootでWeb-Filterを設定する方法(Spring Security)2022/03/15 22:16:37
- [Java] JWT(Json Web Token)を発行、確認する方法2022/03/14 19:12:58
- [Java] 61. Spring bootでRedisデータベースを利用してセッションクラスタリング設定する方法2022/03/01 18:20:52
- [Java] 60. Spring bootでApacheの連結とロードバランシングを設定する方法2022/02/28 18:45:48
- [Java] 59. Spring bootのJPAでEntityManagerを使い方2022/02/25 18:27:48
- [Java] 58. EclipseでSpring bootのJPAを設定する方法2022/02/23 18:11:10
- [Java] 57. EclipseでSpring bootを設定する方法2022/02/22 19:04:49
- [Python] Redisデータベースに接続して使い方2022/02/21 18:23:49
- [Java] Redisデータベースを接続して使い方(Jedisライブラリ)2022/02/16 18:13:17
- [C#] Redisのデータベースを接続して使い方2022/02/15 18:46:09
- [CentOS] Redisデータベースをインストールする方法とコマンドを使い方2022/02/14 18:33:07