1.ThreadLocal
threading的local()函数主要是用来封装公共资源,使得同一个公共资源在不同线程之间得以隔离。这句话该如何理解呢?举个例子说明下!假设现在有一个大箱子(相当于公共资源),每个人(相当于各个线程)将自己的手机放入这个大箱子里。如果不做任何控制的话,当人们从大箱子中取出手机时极有可能会出现取错的情况(找不到自己当初放入的手机)。
实例:
# -*- coding: utf-8 -*-
# @Time : 2022/4/17 16:06
# @File : threadlocal.py
# @Software : PyCharm
import threading
from threading import Lock, RLock
import time
global_telephone = -1
lock = Lock()
def set_telephone(telephone):
global global_telephone
global_telephone = telephone
print(threading.current_thread().name, " 放入的手机是:", global_telephone)
time.sleep(1)
get_telephone()
def get_telephone():
lock.acquire()
try:
print(threading.current_thread().name, " 取出的手机是:", global_telephone)
finally:
lock.release()
if __name__ == '__main__':
for i in range(3):
thread = threading.Thread(target=set_telephone, name='学生' + str(i), args=('手机' + str(i),))
thread.start()
运行结果:
学生0 放入的手机是: 手机0
学生1 放入的手机是: 手机1
学生2 放入的手机是: 手机2
学生0 取出的手机是: 手机2
学生1 取出的手机是: 手机2
学生2 取出的手机是: 手机2
使用local()函数的话,就相当于对这个大箱子进行管理。当每个人放入手机的时候做一个标记(比如在手机上标记所有者的姓名)并隔离放置到箱子中。这样当人们从大箱子中取出手机就能准确的找到自己当初放入的手机。
改写如下:
# -*- coding: utf-8 -*-
# @Time : 2022/4/17 16:06
# @File : threadlocal.py
# @Software : PyCharm
import threading
from threading import Lock, RLock
import time
# global_telephone = -1
lock = Lock()
def set_telephone(telephone):
#global global_telephone
local.telephone = telephone
print(threading.current_thread().name, " 放入的手机是:", local.telephone)
time.sleep(1)
get_telephone()
def get_telephone():
lock.acquire()
try:
print(threading.current_thread().name, " 取出的手机是:", local.telephone)
finally:
lock.release()
if __name__ == '__main__':
local = threading.local()
for i in range(3):
thread = threading.Thread(target=set_telephone, name='学生' + str(i), args=('手机' + str(i),))
thread.start()
运行结果:
学生0 放入的手机是: 手机0
学生1 放入的手机是: 手机1
学生2 放入的手机是: 手机2
学生1 取出的手机是: 手机1
学生0 取出的手机是: 手机0
学生2 取出的手机是: 手机2
可以看出每个学生放入的手机和最终取出的手机是一致的。
小结: 一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题。