Python learning--ThreadLocal

In a multithreaded environment, each thread has its own data. It is better for a thread to use its own local variables than to use global variables, because local variables can only be seen by the thread itself and will not affect other threads, and the modification of global variables must be locked .

But local variables also have a problem, that is, it is troublesome to pass when the function is called:

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)

Every function is called layer by layer so that the parameters are passed. Use global variables? Nor, because each thread processes different Student objects and cannot be shared.

How about using a global dict to store all Student objects, and then using thread itself as the key to obtain the Student object corresponding to the thread?

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()]
    ...

This method is theoretically feasible, and its biggest advantage is that it eliminates the problem of passing std objects in each layer of functions. However, the code for obtaining std for each function is a bit ugly.

Is there an easier way?

ThreadLocal came into being. No need to search dict, ThreadLocal will do it for you automatically:

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()

Results of the:

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

The global variable local_school is a ThreadLocal object, and each Thread can read and write student attributes to it, but does not affect each other. You can treat local_school as a global variable, but each attribute is like local_school. Students are all local variables of threads, which can be read and written at will without interfering with each other, and there is no need to manage locks, which will be handled internally by ThreadLocal.

It can be understood that the global variable local_school is a dict, not only local_school.student can be used, but also other variables such as local_school.teacher can be bound.

The most commonly used place for ThreadLocal is to bind a database connection, HTTP request, user identity information, etc. for each thread, so that all the processing functions called by a thread can access these resources very conveniently.

summary

A ThreadLocal variable, but each thread can only read and write an independent copy of its own thread without interfering with each other . ThreadLocal solves the problem of passing parameters between various functions in a thread.

Guess you like

Origin blog.csdn.net/qq_44787943/article/details/112592076