天天看點

werkzeug: LocalStack作為線程隔離對象棧的基本特性

原文 

 

Werkzeug 通過自定義 werkzeug.local.Local 類實作線程隔離的棧結構, 封裝了push, pop, 和top方法.可以将對象推入、彈出,也可以快速拿到棧頂對象. 同樣具有線程隔離的作用. 并沒有直接使用threading.Local .

  1. LocalStack作為棧結構的特性

棧是一種先進後出的基本資料結構.

from werkzeug.local import LocalStack
s = LocalStack()
s.push()
print(s.top)
print(s.top)  # 擷取棧頂元素
print(s.pop())  # 彈出棧頂元素
print(s.top)  # 彈出的棧頂元素會删除

s.push()
s.push()
print(s.top) 
print(s.top)
print(s.pop())
print(s.pop())
           
  1. 作為線程隔離的特性

線程隔離的作用是: 使目前對象可以正确的使用自己建立的對象, 而不會使用和破壞其他程序的對象.

my_stack = LocalStack()
my_stack.push()
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()
    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()
print('finally, in new thread , value is', my_stack.top)
           

列印結果為:

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

源代碼

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__是一個函數,用來識别目前線程或協程.