flask实现上下文的思想

一、前言

了解过flask的人都知道,flask的核心莫过于它的请求上下文,那么它的实现思想是什么呢?
在讲解这个问题之前,我们要知道Flask中的request是全局的,不是像django中把request携带在视图函数的参数里面,这样便于区分不同的请求,那么flask中全局的request是怎么区分的呢?在多线程中,我们知道多个线程是共享资源的,故而会产生死锁等现象,那么我们想象在我们的Web应用中,每个用户的请求是一个线程,那么该怎么处理呢?

在探索这个问题之前,我们要先了解一下,Threading.local

二、Threading.local

这个方法就解决了多线程中,多个线程的共享资源的问题,假如多个线程在共享一个全局变量,这个方法就会把在每个线程的内部保存一份这个变量,也就是说在不同的线程里面赋值不会覆盖之前的值,因为每个线程里面都有一个单独的空间来保存这个数据,而且这个数据是隔离的,其他线程无法访问

我们来看一段程序:

from threading import local

import threading

class Coo(local):  #继承这个类之后,打印的结果就有顺序了
    pass

coo = Coo()
def add(i):
    coo.num = i
    time.sleep(1)
    print(coo.num,i,threading.current_thread().ident)


for i in range(20):
    th = threading.Thread(target=add,args=(i,))
    th.start()
#打印结果:(在cmd解释器环境下运行,不然打印结果会很乱)
# 1 1 5520
# 0 0 13488
# 5 5 2732
# 3 3 6428
# 8 8 15200
# 7 7 17136
# 12 12 13968
# 10 10 17652
# 19 19 19688
# 17 17 13388
# 14 14 18576
# 4 4 20768
# 6 6 15736
# 11 11 18488
# 18 18 20616
# 15 15 2968
# 13 13 10836
# 16 16 10608
# 9 9 10060
# 2 2 2920

从打印结果,我们就可以看出,多个线程之间是没有出现资源竞争的情况的,所以,也就说明了这个local起到的神奇作用,最最重要的是他们实现了并发(由于cpyhton的GIL锁的机制,cpython中是没有真正意义上的多线程并行)

三、解决多线程资源竞争,为什么不加互斥锁呢?

想象一下,一个线程要等待1秒钟,那么第20个线程,就要等待19秒后才能开始获得资源执行,在web应用中,这个是不可能被允许存在的情况的。

四、这个Threading.local和flask有什么关系呢?

flask的请求上下文其实就是用到了这种思想,flask自定义了类似于thread.local类,为了支持协程,将其唯一标识改为协程的唯一标识,利用线程或者协程的id来区分不同的请求,从而实现上下文机制。

如果想知道,在flask中请求保存的结构,可以看我的上一篇博客,对flask请求上下文的源码分析。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值