Python でのマルチスレッド

Vaibhav Vaibhav 2022年4月12日
Python でのマルチスレッド

マルチスレッドとは、単一のプロセス内で複数のスレッドを同時に実行する手法を指します。同時実行は、コンピューターシステムの可能性を最大限に活用し、通常よりもさらに高速にタスクを実行することを目的としています。

スレッドは非常に軽量で、プロセスと比較してメモリフットプリントが低くなっています。それらは非常に軽量であるため、新しいスレッドの作成は迅速なプロセスです。スレッドを実行すると、実行に必要なシステムリソース(メモリなど)が少なくなります。

スレッドはプロセスの一部であるため、親プロセスまたはスレッドを作成したプロセスとメモリスペースを共有します。マルチスレッドは印象的すぎるように見えるかもしれませんが、輝くものすべてが金であるわけではありません。デッドロックや競合状態に陥るのはごく普通のことなので、スレッドを操作するときは注意が必要です。残念ながら、Python の GIL またはグローバルインタープリターロックにより、Python によって作成されたスレッドはインターリーブを提供し、並列ではなく順次実行されます。

Java などの他のプログラミング言語のスレッドとの真の並列処理を発見できます。Python を使用して複数の CPU コアの恩恵を受ける必要がある場合は、マルチプロセッシング(さまざまなプロセスを並行して実行する手法)を検討する必要があります。

それでも、Python である程度マルチスレッドを実行できます。この記事では、Python を使用してマルチスレッドを実行する方法を学習します。

Python でのマルチスレッド

Python のスレッドライブラリを使用して、Python でマルチスレッドを実行できます。これは、公式の Python がプリインストールされた組み込みモジュールであり、Python でスレッドベースの並列処理を提供することを目的としています。このモジュールとその提供内容の詳細については、公式ドキュメントこちらを参照してください。

ここで、このライブラリを使用してマルチスレッドを実行する方法を理解しましょう。同じことについては、次の Python コードを参照してください。

import threading


class MyThread(threading.Thread):
    def __init__(self, low, high):
        super(MyThread, self).__init__()
        self.low = low
        self.high = high
        self.total = 0

    def run(self):
        for x in range(self.low, self.high):
            self.total += x

    def __str__(self):
        return f"Low: {self.low} | High: {self.high}"


thread_one = MyThread(0, 500000)
thread_two = MyThread(5000000, 10000000)
thread_one.start()
thread_two.start()
thread_one.join()
thread_two.join()
result = thread_one.total + thread_two.total
print("Result:", result)

出力:

Result: 37624997250000

threading モジュールは、別のスレッドで実行されるアクションを表すクラス Thread を提供します。アクションには、数学的計算、API エンドポイントへの POST または GET リクエスト、事前にトレーニングされた機械学習モデルからの出力の取得、大量の分析のスライスなどがあります。

上記の Python コードの MyThread クラスと同様に、Thread クラスを継承する新しいクラスを作成する必要があります。次に、Thread クラスには、オーバーライドする必要のある run() メソッドがあります。この関数には、アクティブ化されたときにスレッドが実行する実際のタスクまたは計算が含まれています。

ご覧のとおり、上記の Python コードの run() 関数をオーバーライドしました。上記の run() 関数は、基本的に、クラス属性 low および high で定義された範囲でループします。範囲内のすべての整数を別のクラス属性 total に追加します。

クラスの簡単な説明が終わったので、プログラムがどのように機能するかを理解しましょう。前の手順を参照してください。

  1. 2つのスレッド、つまり thread_onethread_two が生成または作成されます。
  2. 次に、両方のスレッドの start() メソッドが呼び出されます。start() メソッドは、run() メソッドを実行します。
  3. 次に、両方のスレッドに対して join() メソッドが呼び出されます。このメソッドは、両方のスレッドが終了する前に互いに待機していることを確認します。最初のスレッドが 2 番目のスレッドの 5 秒前にタスクを完了したとしましょう。プログラムをさらに実行させると、2 番目のスレッドがまだそのタスクで実行されていないため、奇妙なバグが発生します。join() メソッドは、他のすべてのスレッドがタスクを完了しない限り、スレッドが終了しないようにします。
  4. 最後に、両方のスレッドの結果が合計され、結果がコンソールに出力されます。

呼び出されたスレッドは、他のスレッドが実行を完了するのを待つ必要があることに注意してください。そうしないと、間違った結果やエラーが発生する可能性があります。

クラススレッドの詳細については、公式ドキュメントこちらを参照してください。

著者: Vaibhav Vaibhav
Vaibhav Vaibhav avatar Vaibhav Vaibhav avatar

Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.