PythonプロセスとスレッドのThreadLocal

Pythonの研究ノート、特別な記録、あなたと共有してください、私はそれが皆に役立つことを願っています。

ThreadLocal

マルチスレッド環境では、各スレッドに独自のデータがあります。ローカル変数はスレッド自体だけが見ることができ、他のスレッドには影響を与えず、グローバル変数の変更をロックする必要があるため、スレッドはグローバル変数を使用するよりも独自のローカル変数を使用する方が適切です。

ただし、ローカル変数にも問題があります。つまり、関数が呼び出されたときに渡すのは非常に面倒です。

def process_student(name):
    std = Student(name)
    # std是局部变量,但是每个函数都要用它,因此必须传进去:
    do_task_1(std)
    do_task_2(std)

def do_task_1(std):
    do_subtask_1(std)
    do_subtask_2(std)

def do_task_2(std):
    do_subtask_2(std)
    do_subtask_2(std)

各関数のパラメーターをレイヤーごとに渡すのはどうですか?グローバル変数を使用しますか?また、各スレッドは異なるStudentオブジェクトを処理し、共有できないため、機能しません。

グローバルdictを使用してすべてのStudentオブジェクトを格納し、スレッド自体をキーとして使用して、スレッドに対応するStudentオブジェクトを取得するとどうなりますか?

global_dict = {}

def std_thread(name):
    std = Student(name)
    # 把std放到全局变量global_dict中:
    global_dict[threading.current_thread()] = std
    do_task_1()
    do_task_2()

def do_task_1():
    # 不传入std,而是根据当前线程查找:
    std = global_dict[threading.current_thread()]
    ...

def do_task_2():
    # 任何函数都可以查找出当前线程的std变量:
    std = global_dict[threading.current_thread()]
    ...

この方法は理論的には実行可能であり、その最大の利点は、関数の各レイヤーでstdオブジェクトを渡す問題がなくなることですが、各関数のstdを取得するためのコードは少し見苦しいです。

もっと簡単な方法はありますか?

ThreadLocalが誕生しました。dictを検索する必要はありません。ThreadLocalが自動的に検索します。

import threading

# 创建全局ThreadLocal对象:
local_school = threading.local()

def process_student():
    std = local_school.student
    print 'Hello, %s (in %s)' % (std, threading.current_thread().name)

def process_thread(name):
    local_school.student = name
    process_student()

t1 = threading.Thread(target=process_thread, args=('Alice',), name='Thread-A')
t2 = threading.Thread(target=process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()

結果:

Hello, Alice (in Thread-A)
Hello, Bob (in Thread-B)

Process finished with exit code 0

グローバル変数local_schoolはThreadLocalオブジェクトであり、各スレッドはそれに学生属性を読み書きできますが、相互に影響を与えることはありません。local_schoolはグローバル変数と考えることができますが、local_school.studentなどの各属性はスレッドのローカル変数であり、相互に干渉することなく自由に読み書きでき、ロックの問題を管理する必要はありません。 、これはThreadLocalによって内部的に処理されます。

グローバル変数local_schoolはdictであり、local_school.studentを使用できるだけでなく、local_school.teacherなどの他の変数をバインドすることもできます。

ThreadLocalの最も一般的な場所は、各スレッドのデータベース接続、HTTP要求、ユーザーID情報などをバインドすることです。これにより、スレッドによって呼び出されるすべての処理関数がこれらのリソースに非常に便利にアクセスできます。

おすすめ

転載: blog.csdn.net/qq_36478920/article/details/99980041