flask上下文
一、threading.local对象
用于为每个线程开辟一块空间来保存它独有的值
不支持多协程
import threading local_values=threading.local() def func(num): local_values.name=num import time time.sleep(1) print(local_values.name,threading.current_thread().name) for i in range(20): th=threading.Thread(target=func,args=(i,),name='线程%s'%i) th.start()
二、自定义类似threading.local对象
为了支持单进程单线程下的并发,那就需自定义类似threading.local对象,并且支持协程
import threading try: from greenlet import getcurrent as get_ident #可获取协程唯一标识 except ImportError: try: from thread import get_ident except ImportError: from _thread import get_ident #获取线程的唯一标识 class Local(object): def __init__(self): self.storage={} self.get_ident=get_ident def set(self,k,v): ident=self.get_ident() origin=self.storage.get(ident) if not origin: origin={k:v} else: origin[k]=v self.storage[ident]=origin def get(self,k): ident=self.get_ident() origin=self.storage.get(ident) if not origin: return None return origin.get(k,None) local_values=Local() def task(num): local_values.set('name',num) import time time.sleep(1) print(local_values.get('name'),threading.current_thread().name) for i in range(20): th=threading.Thread(target=task,args=(i,),name=('线程 %s'%i)) th.start()
三、flask中的实现方法
import threading try: from greenlet import getcurrent as get_ident # 协程 except ImportError: try: from thread import get_ident except ImportError: from _thread import get_ident # 线程 class Local(object): def __init__(self): object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__ident_func__', get_ident) def __getattr__(self, name): try: return self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) def __setattr__(self, name, value): ident = self.__ident_func__() storage = self.__storage__ try: storage[ident][name] = value except KeyError: storage[ident] = {name: value} def __delattr__(self, name): try: del self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) local_values = Local() def task(num): local_values.name = num import time time.sleep(1) print(local_values.name, threading.current_thread().name) for i in range(20): th = threading.Thread(target=task, args=(i,),name='线程%s' % i) th.start()
总结:就是根据线程和协程唯一标识将数据分隔开来,数据永远不会混淆
四、flask的request请求流程


浙公网安备 33010602011771号