Python でスレッドから戻り値を取得する

Dr. Muhammad Abdullah 2023年6月21日
  1. Python でマルチスレッドを使用したHelloWorldプログラム
  2. Python のスレッドで実行されている関数から戻り値を取得する
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) を定義し、nameid の 2つの引数を受け取ります。 Thread クラスで args を使用してこれらの引数をタプルとして渡しました。

2つの Thread クラス オブジェクトを作成し、引数 args=("Thread 1", 1)args=("Thread 2", 2) をそれぞれ thread_1thread_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_argureturn_val の 2つの引数を受け取る関数 first_function を定義しています。 first_functionfirst_argu の値を表示し、戻り値を return_val0 インデックスに配置します。

Thread クラスを使用してスレッドを作成し、thread_1thread_2 のリスト args=("Thread 1", return_val_from_1) args=("Thread 2", return_val_from_2) を含む 2つの引数をそれぞれ渡します。 return_val_from_1return_val_from_2 は、関数から値を取得するために使用されます。

thread_1.join()thread_2.join() は、メイン プログラムが両方のスレッドを完了するのを待つために使用されます。

上記のコード スニペットの出力を見てみましょう。

Python スレッドの戻り値 - 出力 1

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() メソッドから返されます。

次のコードの出力は次のとおりです。

Python スレッドの戻り値 - 出力 2

関連記事 - Python Threading