werkzeug 中localstack的理解

首先最近在学习flask的时候,对flask上下文的原理不是太清楚,关于localstack的实现逻辑不是很清楚,于是各种百度了解了下,这里写过博客备忘下,首先在理解localstack之前,我们要先了解下python自带的thread.local。

thread.local(代码都是伪代码实现,主要是说明下逻辑)

假如我们现在线程里面实现一个循环,肯定是在线程里面定义一个局部变量a,然后对a进行循环操作:

def xh():
    for i in range(a):
        print i
 t1 = Thread(target=xh,name="xunhuan")
 t1.start()
t1.join()

但是如果我们想公用一个全局变量a的话,就会有些麻烦了,只能把a当作参数传递到函数中去,而且如果在方法里面还要对a的值修改的话,还得加锁,要不然多个线程会导致数据不一致,操作起来很麻烦,于是thread.local诞生了,thread.local对象有一个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()

到这里大家对python自带的threadlocal有了一定的理解,threadlocal虽然很好的解决了我们的问题,但是对于一些并发应用还是有些不足,比如我们web应用,服务器对每个请求都会开启一个线程去响应用户的请求,而去响应这个请求的就是我们web应用,对于这种每个请求一个线程的情况,我们上下文完全可以通过threadlocal来实现,但是我们web服务的一个线程并不是只处理一个请求的,可能个请求的后续请求都是这个线程在处理,这个时候我们的上下文就会问题了,而且现在还有了用协程来处理并发的情况,一个线程是可以有多个协程的,所以这个时候threadlocal 就无法满足了,于是werkzeug 贴心的给了一个新的选择

werkzeug.local/localstack

local与python自带的thread.local的区别在于,local支持了协程,字典里的key存的是线程的数值信息或者协程的数值信息,而localstack则是对local的二次封装,并且数据结构不再是字典而是栈;
当有新的请求的时候,会生成新的请求上下文,并且压入(push)栈,这样栈顶永远都是存储的当前请求的上下文,并且localstack提供了一个top方法可以让我们取到这个栈顶对象,但我们的请求结束的时候,会调拥pop方法,将请求上下文移除栈,这样就保证了文并发的情况下,实现了请求上下文的效果

这里演示下,扩展模块flask_login中的current_user

请求开始:
user = localstack()
user .push(current_user)
获取current_user:
current_user = user .top()
请求结束:
user .pop()

这里其实还有个问题,current_user这个时候变量已经生成了,但是如果这个时候我当前的请求已经结束了,user已经被移除栈了,当前的user已经变动了,而我们current_user指向的还是之前的user,如果后续请求如果还是当前的线程在处理的话,current_user对象的信息就不匹配了,所以werkzeug给我们提供了一个代理,localproxy

loaclproxy

通过loaclproxy对象代理,我们就可以保证current_user对象是动态的,时刻保持是最新的user信息

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)
-------
李四
张三

代理的实现原理可能就需要大家去仔细研究了,我是讲不明白的,(:笑哭)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值