Threading.local
作用
为每个线程创建一个独立的空间,使得线程对自己的空间中的数据进行操作(数据隔离)。
import threading from threading import local import time obj = local() def task(i): obj.xxxxx = i time.sleep(2) print(obj.xxxxx,i) for i in range(10): #开启了10个线程 t = threading.Thread(target=task,args=(i,)) t.start()
如何获取一个线程的唯一标记?
线程:threading.get_ident()
协程:greenlet.getcurrent()
根据字典自定义一个类似于threading.local功能?
import time
import threading
DIC = {}
def task(i):
ident = threading.get_ident()
if ident in DIC:
DIC[ident]['xxxxx'] = i
else:
DIC[ident] = {'xxxxx':i }
time.sleep(2)
print(DIC[ident]['xxxxx'],i)
for i in range(10): #开启了10个线程
t = threading.Thread(target=task,args=(i,))
t.start()
根据字典自定义一个为每个协程开辟空间进行存取数据。
import time
import threading
import greenlet
DIC = {}
def task(i):
# ident = threading.get_ident()
ident = greenlet.getcurrent()
if ident in DIC:
DIC[ident]['xxxxx'] = i
else:
DIC[ident] = {'xxxxx':i }
time.sleep(2)
print(DIC[ident]['xxxxx'],i)
for i in range(10): #开启了10个线程
t = threading.Thread(target=task,args=(i,))
t.start()
通过getattr/setattr 构造出来 threading.local的加强版(协程)
import time
import threading
try:
import greenlet
get_ident = greenlet.getcurrent #协程 get_ident相当于全局变量
except Exception as e:
get_ident = threading.get_ident #线程
class Local(object):
DIC = {}
def __getattr__(self, item):
ident = get_ident()
if ident in self.DIC:
return self.DIC[ident].get(item)
return None
def __setattr__(self, key, value):
ident = get_ident()
if ident in self.DIC:
self.DIC[ident][key] = value
else:
self.DIC[ident] = {key:value}
obj = Local()
def task(i):
obj.xxxxx = i
time.sleep(2)
print(obj.xxxxx,i)
for i in range(10): #开启了10个线程
t = threading.Thread(target=task,args=(i,))
t.start()
为什么要做数据隔离?
每个人请求需要做数据隔离,不然会出现数据混乱。每个请求数据不同,需要放在不同的空间,根据线程不同,取不同的值。
真正请求来了之后,会通过local对象为他创造一块空间,每个请求来都会做个数据隔离

浙公网安备 33010602011771号