Pythonでasyncioを使ったプロセスのスポーンと管理

この記事では、Pythonの非同期I/Oライブラリである`asyncio`を使って、プロセスをスポーン(生成)し、管理する方法を詳しく解説します。具体的なコード例とその解説、応用例を含めています。

目次

はじめに

プロセスのスポーンと管理は、サーバーアプリケーションやデータ処理、バッチジョブなど多くの場面で必要とされます。`asyncio`は、このようなタスクを非同期で行うための便利な方法を提供しています。

基本的なプロセスのスポーン

Pythonの`asyncio`ライブラリを用いることで、非同期的にプロセスを生成することができます。

基本的なコード例

以下は、`asyncio`を用いた簡単なプロセスの生成の例です。

import asyncio

async def run_command(*args):
    # 非同期でプロセスをスポーン
    process = await asyncio.create_subprocess_exec(
        *args,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )
    
    # プロセスの終了を待つ
    stdout, stderr = await process.communicate()

    if process.returncode == 0:
        print(f"[stdout]\n{stdout.decode().strip()}")
    else:
        print(f"[stderr]\n{stderr.decode().strip()}")

asyncio.run(run_command("ls", "-l"))

コードの詳細解説

1. `asyncio.create_subprocess_exec()`:非同期で外部コマンドを実行するための関数です。
2. `stdout=asyncio.subprocess.PIPE`と`stderr=asyncio.subprocess.PIPE`:標準出力と標準エラー出力をそれぞれ取得します。
3. `await process.communicate()`:プロセスが終了するまで待ち、その結果を取得します。

応用例

複数のプロセスを並行して実行

複数のプロセスを非同期で並行して実行する例です。

import asyncio

async def run_multiple_commands(commands):
    tasks = []
    for cmd in commands:
        tasks.append(run_command(*cmd))
    await asyncio.gather(*tasks)

commands = [("ls", "-l"), ("date"), ("whoami")]
asyncio.run(run_multiple_commands(commands))

コードの詳細解説

1. `asyncio.gather(*tasks)`:複数の非同期タスクを同時に実行します。
2. `commands = [(“ls”, “-l”), (“date”), (“whoami”)]`:実行するコマンドをリストで管理しています。

コマンドの実行時間を計測

コマンドの実行にかかる時間を計測する例です。

import time

async def run_command_with_time(*args):
    start_time = time.time()
    await run_command(*args)
    elapsed_time = time.time() - start_time
    print(f"{args[0]} took {elapsed_time:.2f} seconds")

asyncio.run(run_command_with_time("sleep", "3"))

コードの詳細解説

1. `time.time()`:現在の時刻(UNIXタイムスタンプ)を取得します。
2. `elapsed_time = time.time() – start_time`:実行時間を計算します。

まとめ

この記事では、`asyncio`を使って非同期にプロセスをスポーンし、管理する方法について解説しました。基本的な方法から応用例まで詳しく見てきたので、これを活用して効率的なプロセス管理を行いましょう。

コメント

コメントする

目次