线程的唯一标记
threading.local
作用:为每个线程开辟一块空间进行数据存储
自定义Local对象:
作用:为每个线程(协程)开辟一块空间进行数据存储
线程的唯一标记get_ident
from threading import Thread from threading import get_ident def task(arg): print(get_ident()) #打印出来的是每一个线程的线程号 for i in range(10): t=Thread(target=task,args=(i,)) t.start()
基于函数自定义Local对象
from threading import Thread from threading import get_ident import time storage = {} #往storage中放数据 def set(k,v): ident = get_ident() if ident in storage: storage[ident][k]=v else: storage[ident]={k:v} #从storage中取数据 def get(k): ident = get_ident() return storage[ident][k] def task(arg): set('val',arg) time.sleep(2) s = get('val') print(s) for i in range(10): t = Thread(target=task,args=(i,)) t.start()
基于面向对象实现的自定义Local对象
from threading import Thread from threading import get_ident import time class Local: storage = {} #往storage中放数据 def set(self,k,v): ident = get_ident() if ident in self.storage: self.storage[ident][k]=v else: self.storage[ident]={k:v} #从storage中取数据 def get(self,k): ident = get_ident() return self.storage[ident][k] obj = Local() def task(arg): obj.set('val',arg) time.sleep(2) s = obj.get('val') print(s) for i in range(10): t = Thread(target=task,args=(i,)) t.start()
基于双下方法实现的自定义Local对象(基于线程(协程))
# from threading import Thread # from threading import get_ident # import time # # # class Scot: # storage = {} # #往storage中放数据 # def __setattr__(self,k,v): # ident = get_ident() # if ident in storage: # storage[ident][k]=v # else: # storage[ident]={k:v} # # # #从storage中取数据 # def __getattr__(self,k): # ident = get_ident() # return storage[ident][k] # # scot = Scot() # # def task(arg): # scot.val=arg # print(scot.val) # # # # for i in range(10): # t = Thread(target=task,args=(i,)) # t.start() ''' 如果这么写如果要实例出多个对象,那么数据都是放在同一个storage中的 想要把他们隔离开,也就是对象都有自己的{},下面代码就实现了 ''' from threading import Thread try: from greenlet import getcurrent as get_ident except Exception: from threading import get_ident #基于线程来做的 import time #基于协程做的 ,两种都可以 class Local: # storage = {} def __init__(self): # self.storage={} #如果没有使用父类的__setattr__,也就是没有第51行的话,这一句代码还没有创建字典就调用了自己的 # __setattr__方法,在else中又调用__setattr__,就一直在调用,所以就出问题了,所以使用父类的这个方法就不会出现问题了 object.__setattr__(self,'storage',{}) #往storage中放数据 def __setattr__(self,k,v): ident = get_ident() if ident in self.storage: self.storage[ident][k]=v else: self.storage[ident]={k:v} #从storage中取数据 def __getattr__(self,k): ident = get_ident() return self.storage[ident][k] obj = Local() def task(arg): obj.val=arg print(obj.val) for i in range(10): t = Thread(target=task,args=(i,)) t.start()