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请求流程

 

posted @ 2018-04-16 11:44  星雨5213  阅读(77)  评论(0)    收藏  举报