threading.local和高级
threading.local特点
①为每个线程开辟空间,让你进行存取值(根据线程ID来固定某个值)
②flask中没有threading.local,但是flask中的上下文管理的思想是借鉴的threading.local.
③在线程关闭之前值保持不变,线程关闭后值就清空了.
普通多线程
import time import threading class Foo(object): def __init__(self): self.num = 0 val2 = Foo() def task(i): val2.num = i time.sleep(1) print(val2.num) for i in range(4): t = threading.Thread(target=task,args=(i,)) t.start() 结果: 3 3 3 3 4个值全一样
threading.local多线程
import time import threading # 当每个线程在执行 val1.xx=1 ,在内部会为此线程开辟一个空间,来存储 xx=1 # val1.xx,找到此线程自己的内存地址去取自己存储 xx val1 = threading.local() def task(i): val1.num = i time.sleep(1) print(val1.num) for i in range(4): t = threading.Thread(target=task,args=(i,)) t.start 输出结果: 0 1 2 3 四个结果不同
自定义threading.local
import threading """ storage = { #自定义的维护一个这样的字典 1111:{'x1':0}, 1112:{'x1':1} 1113:{'x1':2} 1114:{'x1':3} 1115:{'x1':4} } """ class Local(object): def __init__(self): object.__setattr__(self,'storage',{}) def __setattr__(self, key, value): ident = threading.get_ident() #这个就是线程id if ident in self.storage: self.storage[ident][key] = value else: self.storage[ident] = {key:value} def __getattr__(self, item): ident = threading.get_ident() #这个就是线程id if ident not in self.storage: return return self.storage[ident].get(item) local = Local() def task(arg): local.x1 = arg print(local.x1) for i in range(5): t = threading.Thread(target=task,args=(i,)) t.start()
输出:
0
1
2
3
4
会根据你不同的线程ID来输出不同的值
加强版自定义threading.local
flask的上下文管理就这样
原来维护的是一个字典里面还是字典: """ storage = { 1111:{'x1':0}, 1112:{'x1':1} 1113:{'x1':2} 1114:{'x1':3} 1115:{'x1':4} } """ 加强版维护的是一个字典里面是字典加列表: """ storage = { 1111:{'x1':[0,1]}, 1112:{'x1':[0,1,2]} 1113:{'x1':[0,1,3]} 1114:{'x1':[0,1,5]} 1115:{'x1':[0,1,6]} } """ 这个维护的列表要当做栈(append往里加,如果是取值就用[-1],要是拿走值就用pop)来使用,后进先出 import threading """ storage = { 1111:{'x1':[]}, 1112:{'x1':[]} 1113:{'x1':[]} 1114:{'x1':[]} 1115:{'x1':[]}, 1116:{'x1':[]} } """ class Local(object): def __init__(self): object.__setattr__(self,'storage',{}) def __setattr__(self, key, value): ident = threading.get_ident() if ident in self.storage: self.storage[ident][key].append(value) else: self.storage[ident] = {key:[value,]} def __getattr__(self, item): ident = threading.get_ident() if ident not in self.storage: return return self.storage[ident][item][-1] local = Local() def task(arg): local.x1 = arg print(local.x1) for i in range(5): t = threading.Thread(target=task,args=(i,)) t.start()
输出:
0
1
2
3
4