重启博客,记录一些零散的知识和复习学习过的知识
今天记录的是关于localstack的一些知识,首先需要讲到python原生的threadlocal
a = 10 import threading def test(): print(a) thread = threading.Thread(target=test) thread.start() thread.join()
如上,有一个变量a,若线程相对其进行操作,可以将其作为参数传进去,如果要对其进行修改,则需要加锁,操作起来很麻烦,为了解决这个问题threadlocal出现了,threadlocal有一个map属性,以字典
形式保存数据,其中key为线程的id,value为变量的副本,这样每个线程可以操作自己的变量副本,从而实现了线程的隔离,互不干扰
local = Thread.local() local.g = 10 def xh(): for i in range(local.g): print i t1 = Thread(target=xh,name="xunhuan") t2 = Thread(target=xh,name="xunhuan2") t1.start() t2.start() t1.join() t2.join()
如以上伪代码
flask中的localstack是threadlocal的二次封装,并且localstack支持协程,而threadlocal不支持,而存储数据的数据结构不再是字典,而是栈。
当有新的请求的时候,会生成新的请求上下文,并且压入(push)栈,这样栈顶永远都是存储的当前请求的上下文,并且localstack提供了一个top方法可以让我们取到这个栈顶对象,但我们的请求结束的时候,会调拥pop方法,将请求上下文移除栈,这样就保证了文并发的情况下,实现了请求上下文的效果。
请求开始: user = localstack() user .push(current_user) 获取current_user: current_user = user .top() 请求结束: user .pop()
如以上伪代码
但是这里还有一个问题,就是current_user已经生成,如果当前请求结束,user被移除栈,user发生改变,但是current_user还是指向之前的user,所以在werkzeug中给我们提供了localproxy作为代理
a = user() a.name = 张三 b= user() b.name= 李四 user.push(a) user.push(b) def get_current_user(): return user.top() localproxy= localproxy(get_current_user) print(loclaproxy.name) user.pop() print(localproxy.name)
如以上代码
张三和李四先把存在栈中,定义一个方面取出user,然后通过代理localproxy这个代理进行取出,然后把取出的数据移除栈,代理的机制还待进一步研究
原文地址:https://www.cnblogs.com/HZHST/p/11140594.html
时间: 2024-10-17 12:10:08