Pythonでスレッドローカルデータを管理・使用する方法

この記事では、Pythonにおけるスレッドローカルデータの管理と使用について深く掘り下げます。具体的なコード例とその解説、さらには応用例を含めて説明します。

目次

スレッドローカルデータとは

スレッドローカルデータとは、各スレッドからアクセス可能であるが、スレッド間でデータが共有されない変数のことです。Pythonでは`threading.local`クラスを使用することで、このようなデータを簡単に管理できます。

基本的な使用法

import threading

# スレッドローカルデータを作成
local_data = threading.local()

# データを設定
local_data.value = 5

# データを取得
print(local_data.value)

このコードでは、`threading.local()`でスレッドローカルデータを作成しています。各スレッドでこの`local_data`に値を設定すれば、そのスレッド内でだけその値が利用可能です。

スレッドローカルデータの実用例

データベースコネクションの管理

スレッドごとにデータベースコネクションを持ちたい場合、スレッドローカルデータは非常に便利です。

import threading
import sqlite3

local_data = threading.local()

def init_db_connection():
    local_data.connection = sqlite3.connect('database.db')

def query_db(query):
    if not hasattr(local_data, 'connection'):
        init_db_connection()
    cur = local_data.connection.cursor()
    cur.execute(query)
    return cur.fetchall()

この例では、SQLiteデータベースに対するコネクションをスレッドごとに持っています。各スレッドで`query_db()`関数を呼び出すと、そのスレッド専用のデータベースコネクションが用いられます。

ユーザーセッションの管理

Webアプリケーションで、スレッドごとにユーザー情報を持つことが必要な場合もあります。

local_data = threading.local()

def process_request(request):
    local_data.user = request.user

def get_current_user():
    return local_data.user

この例では、各リクエストが処理されるスレッドで、ユーザー情報をスレッドローカルデータに保存しています。

応用例

リクエストIDの生成と管理

import uuid

local_data = threading.local()

def generate_request_id():
    request_id = uuid.uuid4()
    local_data.request_id = request_id
    return request_id

def get_current_request_id():
    return local_data.request_id

独自のログ情報の追加

import logging

def custom_log():
    if hasattr(local_data, 'request_id'):
        logging.info(f"Request ID: {local_data.request_id}")

これらの応用例では、`uuid`を使ってリクエストIDを生成したり、独自のログ情報を追加する際にスレッドローカルデータを活用しています。

まとめ

スレッドローカルデータはマルチスレッドプログラムで非常に役立つ機能です。特に、データベースコネクションやユーザーセッションなど、スレッドごとに異なるリソースを管理する際に便利です。この記事で紹介した基本的な使用法や実践例、応用例を参考に、より高度なマルチスレッドプログラミングを行ってみてください。

コメント

コメントする

目次