This article mainly introduces Python multithreading variable problem, because of Gil's existence, Python multithreaded programming problem has been a hot topic in the developer, need friends can refer to the
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, without affecting other threads, and changes to global variables must be locked.
But there is also a problem with local variables, which are cumbersome to communicate when the function is called:
?
1 2 3 4 5 6 7 8 9 10 11 12-13 |
def process_student (name): std = student (name) # STD is a local variable, but every function uses it, so it must be passed in: 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) |
Each function has a layer of call to the same argument. Use global variables? Also not, because each thread handles different student objects and cannot be shared.
What if you use a global dict to store all the student objects and then take thread itself as the key to get the threads corresponding to the student object?
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17-18 |
Global_dict = {} def std_thread (name): std = Student (name) # Place STD in global variable global_dict: Global_dict[threading.current_threa D ()] = std Do_task_1 () do_task_2 () def do_task_1 (): # does not pass in the STD, but finds it according to the current thread: std = Global_dict[threading.current_thread ()]. .. Def do_task_2 (): # Any function can find out the STD variable of the current thread: std = global_dict[threading.current_thread ()] ... |
This approach is theoretically feasible, and its biggest advantage is that it eliminates the problem of STD objects passing through each layer of functions, but it's a bit ugly for each function to get STD code.
Is there a simpler way?
Threadlocal is born, do not find dict,threadlocal help you do this automatically:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Import Threading # Create Global threadlocal object: Local_school = threading.local () def process_student (): print ' Hello,%s (in%s) '% (Local_school.student, Threading.current_thread (). Name) def process_thread (name): # binding 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 () |
Execution results:
?
1 2 |
Hello, Alice (in thread-a) Hello, Bob (in Thread-b) |
The global variable Local_school is a Threadlocal object that each thread can read and write to student properties, but does not affect each other. You can think of Local_school as a global variable, but each attribute, such as Local_school.student, is the local variable of the thread, can read and write without interference, do not need to manage the lock problem, threadlocal internal will handle.
Can be understood as a global variable local_school is a dict, not only can use local_school.student, but also can bind other variables, such as Local_school.teacher and so on.
The most common place for threadlocal is to bind a database connection to each thread, HTTP requests, user identities, and so on, so that all of the processing functions invoked by a thread can easily access those resources.