Python でスレッドを作成する

Python でスレッドを作成するには threading モジュールの Thread クラスを使います。関数をスレッドで実行する方法と、クラスを継承して作る方法があります。

関数をスレッドで実行する

最も基本的な方法は、Thread クラスの target 引数に実行したい関数を渡すことです。

import threading

def greet(name):
    print(f"こんにちは、{name}さん!")

# スレッドを作成
thread = threading.Thread(target=greet, args=("田中",))

# スレッドを開始
thread.start()

# スレッドの終了を待つ
thread.join()

args にはタプルで引数を渡します。引数が1つの場合は args=("田中",) のようにカンマを忘れないでください。

キーワード引数を渡す

キーワード引数は kwargs で渡します。

import threading

def greet(name, message="こんにちは"):
    print(f"{message}{name}さん!")

thread = threading.Thread(
    target=greet,
    args=("田中",),
    kwargs={"message": "おはよう"}
)
thread.start()
thread.join()

複数のスレッドを作成する

複数のスレッドを作成して並行処理を行う例です。

import threading
import time

def worker(n):
    print(f"Worker {n} 開始")
    time.sleep(1)
    print(f"Worker {n} 終了")

threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print("すべてのワーカーが終了")

Thread クラスを継承する

より複雑な処理には、Thread クラスを継承する方法もあります。

import threading
import time

class MyThread(threading.Thread):
    def __init__(self, name, delay):
        super().__init__()
        self.name = name
        self.delay = delay
    
    def run(self):
        print(f"{self.name} 開始")
        time.sleep(self.delay)
        print(f"{self.name} 終了")

t1 = MyThread("スレッドA", 2)
t2 = MyThread("スレッドB", 1)

t1.start()
t2.start()

t1.join()
t2.join()

run() メソッドをオーバーライドして、スレッドで実行する処理を定義します。

スレッドに名前を付ける

デバッグしやすくするために、スレッドに名前を付けられます。

import threading

def task():
    print(f"実行中: {threading.current_thread().name}")

t1 = threading.Thread(target=task, name="ダウンローダー")
t2 = threading.Thread(target=task, name="パーサー")

t1.start()
t2.start()
t1.join()
t2.join()

現在のスレッド情報を取得する

import threading

def show_info():
    current = threading.current_thread()
    print(f"名前: {current.name}")
    print(f"ID: {current.ident}")
    print(f"生存中: {current.is_alive()}")

thread = threading.Thread(target=show_info, name="InfoThread")
thread.start()
thread.join()

実行中のスレッド一覧

import threading
import time

def worker():
    time.sleep(2)

threads = [threading.Thread(target=worker) for _ in range(3)]
for t in threads:
    t.start()

# 実行中のスレッド一覧
print(f"アクティブなスレッド数: {threading.active_count()}")
for t in threading.enumerate():
    print(f"  - {t.name}")

スレッドの作成は簡単ですが、複数のスレッドがデータを共有する場合は、同期処理(Lock など)が必要になることを覚えておきましょう。