当サイトは、アフィリエイト広告を利用しています
スレッドとは、プログラムの中で独立して動く実行単位のこと。
通常、Pythonのプログラムは1つの処理(メインスレッド)が順番に実行されるが、
Pythonのマルチスレッドを扱うためのライブラリである「threading」を使う
と複数の処理を同時に進める並行処理を行うことができる
似たような言葉で並行処理と並列処理がある
並行処理は処理AとBを切り替えながら処理すること。
Pythonのthreading モジュールを使ったスレッド処理は並行処理に該当する
シングルスレッドで非同期タスクを切り替えながら
並行処理するasyncioというライブラリもある
詳しくは下記記事で
処理AとBを同時並列で処理すること。
multiprocessingががこれにあたる
I/O待ちの多い処理(ファイル操作・ネットワーク通信・DBアクセス)を
threadingを使って並行処理することで効率的に処理できる。
I/O待ちの多い処理に対してthreadingが向いているのは
CPUをあまり使わず、時間がかかる処理であるため
逆にいうとCPU 集中型処理(例えば、大量の計算や数値処理) では、
複数のスレッドで並列実行したい場合でも、GILの制約によって スレッドが
1つずつしか計算を実行できないため、並列実行が効果を発揮できない
実際にthreadingを使ったマルチスレッド処理を実装する
スレッドで関数を処理するための基本的な流れとしては下記のようになる
最終形としては下記のようになる
import threadingimport time# 関数def task(name, timg):print(f"{name} を開始")time.sleep(timg)print(f"{name} を {timg} 秒待機後に終了")# スレッドの作成(引数を指定、デーモンスレッド、名前設定)thread1 = threading.Thread(target=task, # 実行する関数args=("Task 1",), # args はタプルで位置引数を渡すkwargs={"timg": 2}, # kwargs は辞書でキーワード引数を渡すdaemon=True, # デーモンスレッドとして設定name="Thread-1" # スレッドに名前を付ける)thread2 = threading.Thread(target=task,args=("Task 2",),kwargs={"timg": 1},daemon=True,name="Thread-2")# 処理開始print("すべてのタスク開始")# スレッドを開始thread1.start()thread2.start()# スレッドの終了を待つthread1.join()thread2.join()print("すべてのタスクが完了しました")
細かく解説する
スレッド内で実行する関数を作る
import threadingimport time# 関数def task(name, timg):print(f"{name} を開始")time.sleep(timg)print(f"{name} を {timg} 秒待機後に終了")
並列処理させるため関数を定義
関数を設定したスレッドを作成する
# スレッドの作成(引数を指定、デーモンスレッド、名前設定)thread1 = threading.Thread(target=task, # 実行する関数args=("Task 1",), # args はタプルで位置引数を渡すkwargs={"timg": 2}, # kwargs は辞書でキーワード引数を渡すdaemon=True, # デーモンスレッドとして設定name="Thread-1" # スレッドに名前を付ける)thread2 = threading.Thread(target=task,args=("Task 2",),kwargs={"timg": 1},daemon=True,name="Thread-2")
threading.Thread()メソッドを使ってスレッドを作成する
引数の意味は下記の通り
スレッドが実行する関数を指定(必須)
target関数に渡す引数をタプルで指定(オプション)
target関数に渡すキーワード引数を辞書で指定(オプション)
スレッドをデーモンスレッドにするかどうかを指定(オプション)。
メインプログラムが終了した後もスレッドが続行しているとき
スレッドに名前を付ける(オプション)。
# 処理開始print("すべてのタスク開始")# スレッドを開始thread1.start()thread2.start()
作成したスレッドを並行処理する
# スレッドの終了を待つthread1.join()thread2.join()print("すべてのタスクが完了しました")
スレッドが終了するまで次の処理を行わない
すべてのタスク開始Task 1 を開始Task 2 を開始Task 2 を 1 秒待機後に終了Task 1 を 2 秒待機後に終了すべてのタスクが完了しました
並行処理されているのが確認できる
pythonのマルチスレッド処理を行うためのライブラリ「threading」
について基本的な実装方法をまとめてみた
今後は応用的な使い方についても調べたい