第12章: 非同期処理と並行プログラミング

12-asynchronous-concurrent.webp

この章では、Pythonで非同期処理並行プログラミングを実現する方法について学びます。非同期処理は、プログラムがブロックされることなく複数のタスクを同時に実行できるようにするための重要な技術です。Pythonでは、async/await構文やThreadTaskクラスを使って非同期処理や並行処理を実現できます。

目次

12.1 async/awaitの基本

Pythonでは、asyncおよびawaitキーワードを使って、非同期処理を簡単に実装できます。非同期関数は他の処理を待っている間に、他の処理を実行することができ、全体の効率を向上させます。

基本的な構文

import asyncio

async def hello():
    print("Hello...")
    await asyncio.sleep(1)
    print("...World!")

# イベントループの実行
asyncio.run(hello())

この例では、async関数が定義されており、awaitを使って他の処理を待つことができます。asyncio.sleep(1)で1秒間待機しますが、その間に他のタスクが実行される可能性があります。

12.2 Taskクラスの使い方と例外処理

PythonのTaskクラスは、非同期処理を並行して実行するための基本的な単位です。複数のタスクを同時に実行し、それぞれのタスクが終了するのを待つことができます。

複数のタスクを並行実行

import asyncio

async def task1():
    print("Task 1 started")
    await asyncio.sleep(2)
    print("Task 1 completed")

async def task2():
    print("Task 2 started")
    await asyncio.sleep(1)
    print("Task 2 completed")

async def main():
    # 並行してタスクを実行
    await asyncio.gather(task1(), task2())

# イベントループの実行
asyncio.run(main())

この例では、asyncio.gatherを使ってtask1task2を並行して実行し、どちらのタスクも同時に進行させています。

12.3 並行処理のためのスレッド管理 (Thread, ThreadPool)

非同期処理に加えて、Pythonではthreadingモジュールを使ってスレッドを作成し、並行処理を実現することができます。スレッドは、複数のタスクを同時に実行するための基本的な手段です。

スレッドの基本

import threading

def print_numbers():
    for i in range(5):
        print(i)

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

# メインスレッドも動作
print("Main thread running")

この例では、threading.Threadを使って別のスレッドを作成し、並行して数値を出力しています。

12.4 非同期ストリームとIAsyncEnumerableの使用

Pythonでは、非同期処理で繰り返し処理を行うために、async forループや非同期ジェネレータを使うことができます。これにより、非同期でデータを順次処理することができます。

非同期ジェネレータの例

import asyncio

async def async_generator():
    for i in range(3):
        await asyncio.sleep(1)
        yield i

async def main():
    async for value in async_generator():
        print(value)

asyncio.run(main())

この例では、async_generatorが非同期に値を生成し、async forループでその値を順次処理しています。

12.5 パフォーマンス最適化のためのベストプラクティス

非同期処理や並行処理は、効率的なパフォーマンスを実現するための強力な手段ですが、注意深く使用しなければ逆にパフォーマンスが低下する可能性があります。以下は、パフォーマンス最適化のためのベストプラクティスです。

  • I/Oバウンド処理には非同期処理を使用: ディスクやネットワークなどのI/O操作が多い場合、非同期処理を使って効率的に処理を進めることができます。
  • CPUバウンド処理にはスレッドを使用: 計算負荷が高い処理には、スレッドを使って並行処理を行うことでパフォーマンスが向上します。
  • 適切なタスクの分割: タスクを小さく分割し、複数のタスクを並行して実行することで、効率的に処理を行います。

まとめ

この章では、Pythonにおける非同期処理と並行プログラミングの基本的な概念を学びました。これにより、効率的なプログラムを作成し、複数のタスクを同時に実行するスキルが身につきます。次の章では、GUIアプリケーションの基礎について詳しく見ていきます。

目次