30、LocalStack作为线程隔离对象的意义
30.1 数据结构
限制了某些能力
30.2 线程隔离
# -*- coding=utf-8 -*- import threading import time from werkzeug.local import LocalStack my_stack = LocalStack() my_stack.push(1) print(‘in main thread after push, value is:‘ + str(my_stack.top)) def worker(): # 新线程 print(‘in new thread before push, value is:‘ + str(my_stack.top)) my_stack.push(2) print(‘in new thread after push, value is:‘ + str(my_stack.top)) new_t = threading.Thread(target=worker, name=‘qiyue_thread‘) new_t.start() time.sleep(1)
test/LocalStack.py
30.3 flask为什么需要栈结构
需要栈结构,将两个上下文推到栈中去
30.4 为什么需要LocalStack
需要栈是线程隔离的
30.5 线程隔离意义
是当前线程能够正确引用到他自己所创建的对象,而不是引用到其他线程所创建的对象
(1)用一个变量名(request)同事指向多个线程所创建的多个实例化对象是不可能的
(2)可以做到,在当前线程,在引用request(变量名)可以正确找到当前线程它自己所实例化的Request对象
30.6 请求上下文包含Request对象,所以,Request也是被线程隔离的
session也是线程隔离
30.7 知识梳理
(1)线程隔离对象
LocalStack和local是线程隔离对象
(2)被线程隔离的对象
通过线程隔离对象来创建被线程隔离的对象
(3)flask的核心对象app作为一个属性存在于AppContext的应用上下文下
核心对象app只有一个,是在入口文件创建,在主线程中被创建
(4)多线程编程难点
线程安全
线程隔离
30.8 总结
(1)Local->LocalStack,线程隔离对象实现
Local内部有一个字典,以线程ID号作为key
LocalStack如何实现?LocalStack封装了Local
操作Local,通常使用.去访问下面的属性;使用LocalStack,需要使用那几个常用的方法和属性,push、pop、top
(2)AppContext->RequestContext
请求进来,会被推入到LocalStack的栈中去,同时在请求结束时,AppContext和RequestContext会被pop弹出去
(3)Flask->AppContext Request->RequestContext
AppContext重要特点,将Flask核心对象作为它的一个属性,保存了起来
RequestContext请求上下文,将请求对象Request封装和保存
(4)current_app->(LocalStack.top=Appcontext top.app=Flask)
current_app指向的是LocalStack下面的栈顶元素的一个属性,也就是top.app,Flask的核心对象
栈顶元素为应用上下文
(5)request->(LocalStack.top=RequestContext top.request=Request)
request实际指向的是LocalStack栈顶元素下面的Request请求对象
原文地址:https://www.cnblogs.com/wangmingtao/p/9372611.html