wkt's blog
非学无以致疑,非问无以广识

LocalStack–线程隔离的栈结构

admin~2018年5月16日 /flask/笔记

  Werkzeug 通过自定义 werkzeug.local.Local 类实现线程隔离的栈结构, 封装了push, pop, 和top方法.可以将对象推入、弹出,也可以快速拿到栈顶对象. 同样具有线程隔离的作用. 并没有直接使用threading.Local .

  1. LocalStack作为栈结构的特性

栈是一种先进后出的基本数据结构.

from werkzeug.local import LocalStack
s = LocalStack()
s.push(1)
print(s.top)
print(s.top)  # 获取栈顶元素
print(s.pop())  # 弹出栈顶元素
print(s.top)  # 弹出的栈顶元素会删除

s.push(1)
s.push(2)
print(s.top) 
print(s.top)
print(s.pop())
print(s.pop())

  1. 作为线程隔离的特性

线程隔离的作用是: 使当前对象可以正确的使用自己创建的对象, 而不会使用和破坏其他进程的对象.

my_stack = LocalStack()
my_stack.push(2)
print('in main thread after push , value is ', my_stack.top)  

def my_work():
    print('in new thread before, value is ', my_stack.top)
    my_stack.push(3)
    print('after new thread after push, value is ', my_stack.top)
new_thread = threading.Thread(target=my_work, name='my_work_thread')
new_thread.start()
time.sleep(1)
print('finally, in new thread , value is', my_stack.top)

打印结果为:

in main thread after push , value is  2
in new thread before, value is  None
after new thread after push, value is  3
finally, in new thread , value is 2

源代码

class Local(object):
    __slots__ = ('__storage__', '__ident_func__')

    def __init__(self):
        object.__setattr__(self, '__storage__', {})
        object.__setattr__(self, '__ident_func__', get_ident)
    ...
     def __setattr__(self, name, value):
        ident = self.__ident_func__()
        storage = self.__storage__
        try:
            storage[ident][name] = value
        except KeyError:
            storage[ident] = {name: value}

__slots__限制了Local类只可以有两个属性:__storage__和__ident_func__。从构造函,__storage__是一个字典,而__ident_func__是一个函数,用来识别当前线程或协程.

发表评论

电子邮件地址不会被公开。