フリーランス 技術調査ブログ

フリーランス/エンジニア Ruby Python Nodejs Vuejs React Dockerなどの調査技術調査の備忘録

python 非同期処理について

はじめに

  • pythonで非同期処理をする方法を調べてみました。

同期処理

ライブラリインストール

  • シンプルなPythonのHTTPライブラリをインストールする
pip install requests

requests-docs-ja.readthedocs.io

サンプルコード

  • 2回のHTTPリクエストを同期処理をしながら投げる処理
from timeit import default_timer
import requests


def load_date(delay):
    print(f'Starting {delay} second timer')
    text = requests.get(f'https://httpbin.org/delay/{delay}')
    print(f'Completed {delay} second timer')
    return text


def run_demo():
    start_time = default_timer()

    two_date = load_date(2)
    three_date = load_date(3)

    elapsed_time = default_timer() - start_time
    print(f'The operation took {elapsed_time:.2} seconds')


def main():
    run_demo()


main()

同期処理の実行結果

  • 同期処理を行っているため、全部の処理が完了するまで約6~7秒ほどかかる
# python test.py 
Starting 2 second timer
Completed 2 second timer
Starting 3 second timer
Completed 3 second timer
The operation took 6.6 seconds

非同期処理

ライブラリインストール

  • aiohttpおよびPython用の非同期HTTPクライアント/サーバー。
pip install aiohttp

docs.aiohttp.org

  • asyncio は async/await 構文を使い 並行処理の コードを書くためのライブラリです。こちらはpyhon標準のライブラリ docs.python.org

サンプルコード

  • 上記の同期処理と同じように2つのHTTPを実行するが今度は非同期処理で実行する
from timeit import default_timer
import aiohttp
import asyncio


async def load_date(session, delay):
    print(f'Starting {delay} second timer')
    async with session.get(f'https://httpbin.org/delay/{delay}') as resp:
        text = await resp.text()
        print(f'Completed {delay} second timer')
        return text


async def main():
    start_time = default_timer()

    async with aiohttp.ClientSession() as session:
        two_task = asyncio.create_task(load_date(session, 2))
        three_task = asyncio.create_task(load_date(session, 3))

        await asyncio.sleep(1)
        print('Doing other work')

        two_result = await two_task
        three_result = await three_task

    elapsed_time = default_timer() - start_time
    print(f'The operation took {elapsed_time:.2} seconds')


asyncio.run(main())

実行結果

  • 今度は非同期処理で実行したので、4秒以内で処理が完了した。
# python test.py 
Starting 2 second timer
Starting 3 second timer
Doing other work
Completed 2 second timer
Completed 3 second timer
The operation took 3.9 seconds