##並列処理
スレッドは複数のことを並行して処理(並列処理)する際に使います。
スレッドとは糸のことです。
複数の処理を複数の糸に見立てて、別々の流れで処理されているよ!って感じですね。
複数のスレッドがあることをマルチスレッドと言います。
##プログラム例ースレッドを使わないと・・・
オブジェクト指向の基本で使った例に改良を加えて例としていきます。
下記は、三人(佐藤、田中、山本)をインスタンス化し、各々eatとwalkを繰り返すroutineというメソッドを実行する例です。
import time
# クラスを定義ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
class Human:
def __init__(self,name,weight,walk_distance_km):
# コンストラクタ
self.name=name
self.weight=weight
self.walk_distance_km=walk_distance_km
def eat(self):
#eatメソッド
self.weight=self.weight+1
print(self.name,"さんは食事をしました。今の体重は",round(self.weight,2),"kgです。")
def walk(self, distance_km):
#walkメソッド
self.weight = self.weight - distance_km * 0.1
print(self.name, "さんは", distance_km, "km歩いたことにより体重が", round(self.weight,2), "kgになりました。")
def routine(self):
#routineメソッド eatとwalkを繰り返す
while True:
self.eat()
time.sleep(3)
self.walk(self.walk_distance_km)
time.sleep(3)
# ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
# インスタンス化ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
sato=Human("佐藤",70,3)
tanaka=Human("田中",53,1)
yamamoto=Human("山本",66,2)
# ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
# ルーティーンを実行ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
sato.routine()
tanaka.routine()
yamamoto.routine()
# ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
##実行結果
いつまで経っても田中さんや山本さんのルーティンが開始されません。
三人の体重の変化を見たいのですが、スレッドを使わないと佐藤さんの処理が終わらないと、田中さんや山本さんのルーティンが開始されません。routineメソッドは無限ループなので、田中さんの処理は終わることはありません。
つまり、田中さんや山本さんのルーティンはいつまで経っても始まることはありません。
佐藤 さんは食事をしました。今の体重は 71 kgです。kgです
佐藤 さんは 3 km歩いたことにより体重が 70.7 kgになりました。
佐藤 さんは食事をしました。今の体重は 71.7 kgです。kgです
佐藤 さんは 3 km歩いたことにより体重が 71.4 kgになりました。
##プログラム例ースレッドを使う
import threading
import time
# クラスを定義ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
class Human:
def __init__(self,name,weight,walk_distance_km):
# コンストラクタ
self.name=name
self.weight=weight
self.walk_distance_km=walk_distance_km
def eat(self):
#eatメソッド
self.weight=self.weight+1
print(self.name,"さんは食事をしました。今の体重は",round(self.weight,2),"kgです。")
def walk(self, distance_km):
#walkメソッド
self.weight = self.weight - distance_km * 0.1
print(self.name, "さんは", distance_km, "km歩いたことにより体重が", round(self.weight,2), "kgになりました。")
def routine(self):
#routineメソッド eatとwalkを繰り返す
while True:
self.eat()
time.sleep(3)
self.walk(self.walk_distance_km)
time.sleep(3)
# ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
# インスタンス化ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
sato=Human("佐藤",70,3)
tanaka=Human("田中",53,1)
yamamoto=Human("山本",66,2)
# ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
#スレッドー3人のルーティーンを並列処理する
thread1 = threading.Thread(target=sato.routine)
thread1.start()
time.sleep(0.5)
thread2 = threading.Thread(target=tanaka.routine)
thread2.start()
time.sleep(0.5)
thread3 = threading.Thread(target=yamamoto.routine)
thread3.start()
##実行結果
スレッドを使うと、三人の処理が並列処理されるので、このように三人の体重が表示されます。
佐藤 さんは食事をしました。今の体重は 71 kgです。kgです
田中 さんは食事をしました。今の体重は 54 kgです。kgです
山本 さんは食事をしました。今の体重は 67 kgです。kgです
佐藤 さんは 3 km歩いたことにより体重が 70.7 kgになりました。
田中 さんは 1 km歩いたことにより体重が 53.9 kgになりました。
山本 さんは 2 km歩いたことにより体重が 66.8 kgになりました。
#スレッドのポイント
スレッドは下記のように関数名やメソッド名を指定して実行します。
import threading
thread = threading.Thread(target=関数名やメソッド名)
thread.start()
注意点としては、通常関数やメソッドを実行する際につける ()をつけないをつけないという事です。
例えばroutineという関数を実行する場合、下記のようにして下さい。
thread = threading.Thread(target=routine)#OK
thread = threading.Thread(target=routine())#NG
#Work
Python:オブジェクト指向の基本のWork3で作ったプログラムにルーティンメソッドを追加して、スレッドで実行してみましょう。