Python でスレッドから戻り値を取得する
この記事では、最初にスレッドの基本と、Python でスレッドを開始するためのコードについて説明します。 この後、スレッドで実行されている関数から値の戻り値を取得するコードについて説明します。
スレッドは、独自のプログラム実行状態を持つプロセス内の軽量実行ユニットです。 プロセスは複数のスレッドを実行して、並行性 (場合によっては並列性) を実現します。
プロセスとスレッドの主な違いは、各プロセスが別々の独立したアドレス空間を持っているのに対し、同じプロセスの複数のスレッドが 1つのプロセスの同じアドレス空間を共有していることです。 これは、追加のパイプ (通常のパイプまたは FIFO) やメッセージ パッシング インターフェイスを必要とせずに、スレッドが共有メモリを使用して通信できることを意味します。
Python でマルチスレッドを使用したHelloWorld
プログラム
次のコードを検討してください。
from threading import Thread
# A function for threads.
def first_function():
print("Hello World")
print("main program start")
thread_1 = Thread(target=first_function)
thread_2 = Thread(target=first_function)
thread_1.start()
thread_2.start()
print("main ends")
上記のコードでは、最初に from threading import Thread
ステートメントを使用して Thread
クラスをインポートし、マルチスレッドを使用しました。 Hello World
を表示する関数 first_function()
を定義し、Thread()
クラスを使用してスレッドをインスタンス化しました。
実行する target
関数として first_function()
を渡すことにより、Thread()
クラスの 2つのインスタンスを作成しました。 target
属性は、Thread()
によって実行される関数を指定します。
Thread()
インスタンスが作成されると、.start()
メソッドを使用してこれらのスレッドを実行できます。
スレッドで実行されている関数に引数を渡す
次のコードを検討してください。
from threading import Thread
def first_function(name, id):
print("Hello World from ", name, " ID= ", id)
thread_1 = Thread(target=first_function, args=("Thread 1", 1))
thread_2 = Thread(target=first_function, args=("Thread 2", 2))
thread_1.start()
thread_2.start()
上記のコードでは、関数 first_function(name, id)
を定義し、name
と id
の 2つの引数を受け取ります。 Thread
クラスで args
を使用してこれらの引数をタプルとして渡しました。
2つの Thread
クラス オブジェクトを作成し、引数 args=("Thread 1", 1)
と args=("Thread 2", 2)
をそれぞれ thread_1
と thread_2
に渡しました。 さらに、これらのスレッドを実行するために thread_1.start()
と thread_2.start()
が使用されます。
Python のスレッドで実行されている関数から戻り値を取得する
スレッドで実行されている関数から戻り値を取得するには、さまざまな方法があります。
可変オブジェクトを関数に渡す
関数に変更可能なオブジェクトを渡すことにより、スレッドで実行されている関数から値を取得できます。 関数は戻り値をそのオブジェクトに配置します。 次のコードを検討してください。
from threading import Thread
def first_function(first_argu, return_val):
print(first_argu)
return_val[0] = "Return Value from " + first_argu
return_val_from_1 = [None] * 1
return_val_from_2 = [None] * 1
thread_1 = Thread(target=first_function, args=("Thread 1", return_val_from_1))
thread_2 = Thread(target=first_function, args=("Thread 2", return_val_from_2))
thread_1.start()
thread_2.start()
thread_1.join()
thread_2.join()
print(return_val_from_1)
print(return_val_from_2)
上記のコードは、first_argu
と return_val
の 2つの引数を受け取る関数 first_function
を定義しています。 first_function
は first_argu
の値を表示し、戻り値を return_val
の 0
インデックスに配置します。
Thread
クラスを使用してスレッドを作成し、thread_1
と thread_2
のリスト args=("Thread 1", return_val_from_1)
と args=("Thread 2", return_val_from_2)
を含む 2つの引数をそれぞれ渡します。 return_val_from_1
と return_val_from_2
は、関数から値を取得するために使用されます。
thread_1.join()
と thread_2.join()
は、メイン プログラムが両方のスレッドを完了するのを待つために使用されます。
上記のコード スニペットの出力を見てみましょう。
join
メソッドを使用する
join
メソッドは、スレッドで実行されている関数から戻り値を取得する別の方法です。 次のコードを検討してください。
from threading import Thread
def first_function(first_argu):
print(first_argu)
return "Return Value from " + first_argu
class NewThread(Thread):
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
Thread.__init__(self, group, target, name, args, kwargs)
def run(self):
if self._target != None:
self._return = self._target(*self._args, **self._kwargs)
def join(self, *args):
Thread.join(self, *args)
return self._return
thread_1 = NewThread(target=first_function, args=("Thread 1",))
thread_2 = NewThread(target=first_function, args=("Thread 2",))
thread_1.start()
thread_2.start()
print(thread_1.join())
print(thread_2.join())
上記のコードでは、Thread
クラスのサブクラスである、カスタマイズされたクラス NewThread
を定義しています。 run
および join
メソッドを再定義します。
スレッドを作成して開始すると、first_function
からの戻り値が join()
メソッドから返されます。
次のコードの出力は次のとおりです。