Python

【Python】第7章第12回:並列処理とマルチスレッド

本記事では、Pythonでの並列処理とマルチスレッドについて学びます。プログラムの処理速度を向上させる技術を身につけましょう。

0. 記事の概要

この記事を読むメリット

  • 高速化技術の基礎理解:並列処理とマルチスレッドの違いを学べます。
  • 実践的なスキルの習得:Pythonでの並列処理の実装例を理解できます。
  • スケーラブルなプログラム作成:大規模なタスクを効率的に分割する方法を習得します。

この記事で学べること

  • 並列処理とマルチスレッドの基本概念
  • Pythonでのスレッド操作とパフォーマンスの向上
  • 実践的なコード例と適用場面

1. 並列処理とマルチスレッドの概要

1.1 並列処理とは?

並列処理とは、複数のタスクを同時に実行することで、プログラムの処理速度を向上させる技術です。Pythonでは以下の方法で実現できます。

  • マルチスレッド: 複数のスレッドを使用してタスクを並列化
  • マルチプロセス: 複数のプロセスを使用して負荷を分散
  • 非同期処理: タスクの待ち時間を最小化

1.2 マルチスレッドの特徴

マルチスレッドは、同一プロセス内で複数のスレッドが実行されます。そのため、メモリ消費が少ない反面、PythonのGIL(Global Interpreter Lock)がパフォーマンスに影響する場合があります。

2. Pythonにおける並列処理の基本

2.1 threadingモジュールを使ったマルチスレッド

# マルチスレッドの例
import threading
import time

def print_numbers():
    for i in range(5):
        print(f"Number: {i}")
        time.sleep(1)

# スレッドの作成
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_numbers)

# スレッドの開始
thread1.start()
thread2.start()

# スレッドの終了を待機
thread1.join()
thread2.join()

print("全てのスレッドが終了しました。")

2.2 concurrent.futuresを使った並列処理

# concurrent.futuresによる並列処理
from concurrent.futures import ThreadPoolExecutor

def square(n):
    return n * n

numbers = [1, 2, 3, 4, 5]

# スレッドプールを使用
with ThreadPoolExecutor() as executor:
    results = list(executor.map(square, numbers))

print(results)
動作解説
  • threading: スレッドを生成し、複数のタスクを並列で実行。
  • concurrent.futures: スレッドプールを利用して、効率的なタスク管理を実現。

3. 実践例:並列処理を活用したデータ処理

3.1 スレッドを使用したファイル処理

# スレッドを使った複数ファイルの処理
import threading

def process_file(file_name):
    print(f"{file_name}を処理中...")
    # ファイル処理のコード
    print(f"{file_name}の処理が完了しました。")

files = ["file1.txt", "file2.txt", "file3.txt"]

threads = []
for file in files:
    thread = threading.Thread(target=process_file, args=(file,))
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join()
動作解説
  • スレッドを用いて複数のファイルを並行処理。
  • 各スレッドが独立してタスクを処理するため、高速化を実現。

4. 練習問題

以下の課題に挑戦してみましょう。

  1. 複数のURLに対して並列でリクエストを送信し、結果を取得してください。
  2. マルチスレッドを使って大きなリストを分割し、並列で要素を二乗するプログラムを書いてください。
  3. スレッドの完了時にログを記録する処理を実装してください。

5. 練習問題の解答と解説

問1〜3の解答例

# 問1: 並列リクエスト
import threading
import requests

def fetch_url(url):
    response = requests.get(url)
    print(f"{url}: {response.status_code}")

urls = ["https://example.com", "https://example.org", "https://example.net"]

threads = [threading.Thread(target=fetch_url, args=(url,)) for url in urls]

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

# 問2: リストの並列処理
numbers = list(range(1, 10001))

def square_chunk(chunk):
    return [n * n for n in chunk]

chunk_size = len(numbers) // 4
chunks = [numbers[i:i + chunk_size] for i in range(0, len(numbers), chunk_size)]

with ThreadPoolExecutor() as executor:
    results = executor.map(square_chunk, chunks)

# 問3: スレッド完了時のログ記録
def log_task(task_name):
    print(f"{task_name}が完了しました。")

tasks = ["Task1", "Task2", "Task3"]
threads = [threading.Thread(target=log_task, args=(task,)) for task in tasks]

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

6. まとめ

本記事では、Pythonの並列処理とマルチスレッドの基礎を学びました。これらの技術を応用して、高速でスケーラブルなプログラムを構築してみましょう。