マルチスレッドの基本
マルチスレッドとは、1つのプログラム内で複数のスレッドを同時に実行し、それぞれが異なるタスクを処理する仕組みです。Pythonでは、threadingモジュールを用いてマルチスレッドプログラミングが可能です。この仕組みを利用することで、プログラムの並行処理能力を向上させることができます。
スレッドの作成と起動
以下は、threading.Threadクラスを継承してスレッドを作成し、start()メソッドで起動する例です。
import threading
import time
def thread_task():
print("スレッドが起動しました")
time.sleep(2)
print("スレッドが終了しました")
# スレッドの作成
thread = threading.Thread(target=thread_task)
# スレッドの起動
thread.start()
# スレッドが終了するまで待機
thread.join()
print("すべてのスレッドが終了しました")
この例では、メインスレッドがサブスレッドを待機させ、終了後に処理を継続します。
スレッド間の同期
複数のスレッドが共有リソースを操作する場合、データ競合を防ぐために同期機構が重要です。Pythonのthreadingモジュールでは、ロック機構を用いてスレッド間の同期を管理できます。
import threading
import time
lock = threading.Lock()
def safe_thread_task():
with lock:
print("スレッドがロックを取得しました")
time.sleep(2)
print("スレッドがロックを解放しました")
# 多数のスレッドを作成
threads = [threading.Thread(target=safe_thread_task) for _ in range(3)]
# すべてのスレッドを起動
for thread in threads:
thread.start()
# すべてのスレッドが終了するまで待機
for thread in threads:
thread.join()
print("すべてのスレッドが終了しました")
この例では、ロックを用いてスレッド間の排他制御を行っています。
非同期IOの基本
非同期IOは、IO操作中に他の処理を実行できる非ブロッキング型のIO処理です。Pythonのasyncioモジュールを用いて非同期IOを実現できます。特にIO密集型のタスクにおいて、プログラムの性能を向上させることが可能です。
非同期タスクの作成
非同期関数はasyncキーワードで定義し、awaitキーワードで非同期操作を待機します。
import asyncio
async def async_task():
print("非同期タスクが起動しました")
await asyncio.sleep(2)
print("非同期タスクが終了しました")
# イベントループの作成
loop = asyncio.new_event_loop()
# 非同期タスクの作成
task = loop.create_task(async_task())
# イベントループの実行
loop.run_until_complete(task)
print("すべての非同期タスクが終了しました")
この例では、非同期タスクをイベントループ上で実行しています。
非同期タスクの並行実行
asyncio.gather()メソッドを用いて、複数の非同期タスクを並行して実行できます。
async def main():
tasks = [async_task() for _ in range(3)]
await asyncio.gather(*tasks)
# イベントループの作成
loop = asyncio.new_event_loop()
# 非同期タスクの実行
loop.run_until_complete(main())
print("すべての非同期タスクが終了しました")
この例では、複数の非同期タスクを並行して実行し、処理効率を向上させています。
マルチスレッドと非同期IOの組み合わせ
マルチスレッドと非同期IOを組み合わせることで、より高い並行処理能力を実現できます。特にIO操作とCPU操作を同時に実行する場合、この組み合わせが効果的です。
import threading
import asyncio
async def async_task():
print("非同期タスクが起動しました")
await asyncio.sleep(2)
print("非同期タスクが終了しました")
async def main():
tasks = [async_task() for _ in range(3)]
await asyncio.gather(*tasks)
def thread_worker():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
# 多数のスレッドを作成
threads = [threading.Thread(target=thread_worker) for _ in range(3)]
# すべてのスレッドを起動
for thread in threads:
thread.start()
# すべてのスレッドが終了するまで待機
for thread in threads:
thread.join()
print("すべてのタスクが終了しました")
この例では、各スレッド内にイベントループを生成し、非同期タスクを並行実行しています。