マルチスレッド環境では、各スレッドに独自のデータがあります。ローカル変数はスレッド自体によってのみ表示され、他のスレッドには影響を与えず、グローバル変数の変更はロックする必要があるため、スレッドはグローバル変数を使用するよりも独自のローカル変数を使用する方が適切です。
ただし、ローカル変数にも問題があります。つまり、関数が呼び出されたときに渡すのが面倒です。
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が誕生しました。辞書を検索する必要はありません。ThreadLocalが自動的に検索します。
import threading
# 创建全局ThreadLocal对象:
local_school = threading.local()
def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
# 绑定ThreadLocal的student:
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)
グローバル変数local_schoolはThreadLocalオブジェクトであり、各スレッドはそれに学生属性を読み書きできますが、相互に影響を与えることはありません。local_schoolをグローバル変数として扱うことができますが、各属性はlocal_schoolのようなものです。学生はすべてスレッドのローカル変数であり、互いに干渉することなく自由に読み書きでき、ThreadLocalによって内部的に処理されるロックの問題を管理する必要はありません。
グローバル変数local_schoolはdictであり、local_school.studentを使用できるだけでなく、local_school.teacherなどの他の変数もバインドできることが理解できます。
ThreadLocalの最も一般的な場所は、各スレッドのデータベース接続、HTTP要求、ユーザーID情報などをバインドすることです。これにより、スレッドによって呼び出されるすべての処理関数がこれらのリソースに非常に便利にアクセスできます。
概要
ThreadLocal変数ですが、各スレッドは、相互に干渉することなく、独自のスレッドの独立したコピーのみを読み書きできます。ThreadLocalは、スレッド内のさまざまな関数間でパラメーターを渡す問題を解決します。