请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

请问老师为什么要用栈结构,request上下文对象和falsk核心上下文对象,按照用户请求来的话 应该是不同的线程去处理不同的请求,那为什么要使用栈结构呢?

正在回答 回答被采纳积分+3

2回答

7七月 2018-04-23 03:06:23

终于有人问到这个问题了,这个问题只有深入思考才会发现,一般情况下没有必要用栈结构。但是有两种情况,一种是离线脚本有可能推入多个上下文,另外一种是单元测试。具体可以再查一下资料。这个看资料不是太容易理解,需要自己去编写一些单元测试才能理解。

4 回复 有任何疑惑可以回复我~
  • 这里采用栈隔离,栈是后进先出的,意思是,一下子同时来了很多请求,我最先请求的,岂不是要等他们后来的先处理完,才到最先的?
    回复 有任何疑惑可以回复我~ 2019-08-14 17:40:26
  • 不是的,不同的请求都是不同的线程,没有先来后到,上面老师说了,真实的业务环境,是没有必要用栈的。一个请求来了,都能保证是在当前线程id的栈结构的最上边(top)。只有写单元测试的时候会出现你说的情况。我的理解,不知道对不对
    回复 有任何疑惑可以回复我~ 2019-12-22 13:52:47
Mark24 2018-04-22 21:07:20

我回答下我的思考:

比如部署Flask的时候是多进程部署,每个进程内部又是多线程的Flask监听HTTP请求。

当任何一个请求进入,就会被分配到某个进程的某个线程执行(7月老师讲线程和进程,进程负责执行,没毛病)。

该线程,在该Flask App进程下,就会通过 线程id识别,在 request的栈里,塞入一个对象。这里说是栈结构,实际上这是一个 字典结构,保证彼此隔离,之所以用栈去表达,是想表达保存的意思吧,实际上是用字典;你可以想想下,站在总进程的角度来看,不同线程逐个接收到请求,字典逐个被压入对象,仿佛一个栈,不断地被压入对象。

request的请求,会主动让 app_context_stack压入对应 线程id的一个 flask app实例。

然后你在 g,app_context_stack, request_stack, session 中能够看到,都是字典,他们通过相同的 线程id,保存着对应的对象。访问的时候,都是彼此对应的,当请求解除,也被依次对应的销毁掉。


这里巧妙的地方在于,利用一个字典结构:

  1. 简化了书写,不需要每个view函数都接收四个对象

  2. 过程变得优雅


Flask作者聪明的利用这个设计,把事情变得优雅又简单。这就是他为啥用这个的理由。也是Flask的技术亮点。


上面是个人的一点思考,这里如果有解释不对的,希望各位同学指正。

1 回复 有任何疑惑可以回复我~
  • “这里说是栈结构,实际上这是一个 字典结构,保证彼此隔离,之所以用栈去表达,是想表达保存的意思吧,实际上是用字典;你可以想想下,站在总进程的角度来看,不同线程逐个接收到请求,字典逐个被压入对象,仿佛一个栈,不断地被压入对象。 ”
    ------------
    这个说法个人认为是有问题的。栈的实现是基于列表,而线程隔离的实现是基于字典。个人认为老师的那个图是在单一线程内的展示。麻烦老师斧正。
    回复 有任何疑惑可以回复我~ 2020-11-26 10:33:22
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信