Pythonにおけるマルチスレッドとマルチプロセスの扱いについて深く掘り下げます。具体的なコード例やその解説、応用例も含めています。Pythonでの非同期処理手法について理解を深め、高度なプログラミングスキルを身に付けましょう。
はじめに
Pythonでプログラムを高速化する方法として、マルチスレッドとマルチプロセスがあります。しかし、それぞれの方法には特性と使い道があり、場合によっては選択肢が異なります。この記事では、両者の基礎から応用までを解説します。
マルチスレッドとは
マルチスレッドとは、一つのプロセス内で複数のスレッドを同時に実行する技術です。スレッドはプログラム内での最小の処理単位であり、複数のスレッドが協力してタスクを完遂します。
基本的なコード例
import threading
# スレッドで実行する関数
def print_numbers():
for i in range(10):
print(i)
# スレッドの作成
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_numbers)
# スレッドの開始
thread1.start()
thread2.start()
# スレッドが終了するまで待機
thread1.join()
thread2.join()
コードの解説
このコードは、`print_numbers`という関数を2つのスレッドで並行に実行しています。`threading.Thread`でスレッドを作成し、`start()`でスレッドを開始しています。最後に`join()`で、スレッドが終了するまでメインスレッドが待機します。
マルチプロセスとは
マルチプロセスとは、複数のプロセスを同時に実行する技術です。マルチスレッドが一つのプロセス内で行われるのに対し、マルチプロセスは複数の独立したプロセスが行います。
基本的なコード例
from multiprocessing import Process
# プロセスで実行する関数
def print_numbers():
for i in range(10):
print(i)
# プロセスの作成
process1 = Process(target=print_numbers)
process2 = Process(target=print_numbers)
# プロセスの開始
process1.start()
process2.start()
# プロセスが終了するまで待機
process1.join()
process2.join()
コードの解説
このコードは、マルチスレッドの例と非常に似ていますが、`threading`モジュールではなく`multiprocessing`モジュールを使用しています。`Process`クラスを使い、それぞれのプロセスで`print_numbers`関数が実行されます。
マルチスレッドとマルチプロセスの使い分け
I/Oバウンドの処理(ファイル読み書き、ネットワーク通信など)はマルチスレッド、CPUバウンドの処理(計算処理など)はマルチプロセスが適しています。
応用例
以下は、マルチスレッドとマルチプロセスの応用例です。
マルチスレッドでのWebスクレイピング
import threading
import requests
# スレッドで実行する関数
def fetch_content(url):
response = requests.get(url)
print(response.text[:100])
# URLリスト
urls = ["https://www.example.com", "https://www.example.org", "https://www.example.net"]
# スレッドの作成と開始
threads = []
for url in urls:
thread = threading.Thread(target=fetch_content, args=(url,))
thread.start()
threads.append(thread)
# 全てのスレッドが終了するまで待機
for thread in threads:
thread.join()
解説
この例では、`requests`モジュールを用いてWebスクレイピングをマルチスレッドで行っています。各スレッドが独立してWebページの内容を取得します。
マルチプロセスでの画像処理
from multiprocessing import Process
from PIL import Image, ImageFilter
# プロセスで実行する関数
def apply_filter(image_path):
img = Image.open(image_path)
img = img
.filter(ImageFilter.GaussianBlur(15))
img.save(f"Blurred_{image_path}")
# 画像パスリスト
image_paths = ["image1.jpg", "image2.jpg", "image3.jpg"]
# プロセスの作成と開始
processes = []
for image_path in image_paths:
process = Process(target=apply_filter, args=(image_path,))
process.start()
processes.append(process)
# 全てのプロセスが終了するまで待機
for process in processes:
process.join()
解説
この例では、`PIL`(Pillow)ライブラリを使用して画像にガウシアンブラーを適用しています。画像処理はCPUバウンドなのでマルチプロセスが適しています。
マルチスレッドとマルチプロセスの組み合わせ
from multiprocessing import Process
import threading
import requests
from PIL import Image, ImageFilter
# プロセスで実行する関数(画像処理)
def apply_filter(image_path):
img = Image.open(image_path)
img = img.filter(ImageFilter.GaussianBlur(15))
img.save(f"Blurred_{image_path}")
# スレッドで実行する関数(Webスクレイピング)
def fetch_content(url):
response = requests.get(url)
print(response.text[:100])
# メイン関数
def main():
# マルチプロセスで画像処理
image_paths = ["image1.jpg", "image2.jpg", "image3.jpg"]
processes = []
for image_path in image_paths:
process = Process(target=apply_filter, args=(image_path,))
process.start()
processes.append(process)
# マルチスレッドでWebスクレイピング
urls = ["https://www.example.com", "https://www.example.org", "https://www.example.net"]
threads = []
for url in urls:
thread = threading.Thread(target=fetch_content, args=(url,))
thread.start()
threads.append(thread)
# プロセスとスレッドの終了を待つ
for process in processes:
process.join()
for thread in threads:
thread.join()
if __name__ == '__main__':
main()
解説
この例では、マルチプロセスとマルチスレッドを組み合わせています。画像処理はマルチプロセス、Webスクレイピングはマルチスレッドで行っています。
まとめ
Pythonでのマルチスレッドとマルチプロセスは、それぞれ特性と利点があります。この記事で解説した基本的なコード例と応用例を参考に、自分のプロジェクトに適した非同期処理手法を選びましょう。
コメント