Flask - 上下文管理

1. threading.local对象,用于为每个线程开辟一块空间来保存它独有的值。

Flask的上下文管理借助了这个思想。Thread-local data is data whose values are thread specific

import threading


# class Foo(object):
#     def __init__(self):
#         self.name = 0
#
# local_values = Foo()

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()

如果解注释class Foo,不用threading.local(),那么

因为修改的值始终保存在同一个对象里面,sleep一秒后,全部线程执行完毕,值变成了最后的值19。

2. 单进程单线程多协程中,threading.local会出问题,因为协程数据都存在同一个线程里。

解决方法为:
单进程单线程多协程中,程序不再支持协程,就可以使用threading.local对象。
单进程单线程多协程中,程序想支持协程,那么自定义类似threading.local对象。如下所示



"""
{
   identification:{k:v}
}



"""
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()

猜你喜欢

转载自www.cnblogs.com/allen2333/p/9019367.html