1. 调试环境: 客户端发送10个请求,flask : app.run 单进程单线程 请求一个一个执行,不能大量处理请求
可以开启threaded参数以保证多线程
app.run(debug=app.config['DEBUG'], threaded=True)
2. 部署开发环境: webserver开启多线程 nginx apache tomcat
3. flask的werkzeug的Local对象管理多线程
字典 request = {k:v}
多线程下 每个线程都有唯一标识作为key,请求对象对位value
线程的id号作为键,实现线程隔离
字典 保存数据
操作数据,werkzeug库 local模块 Local对象 实现线程隔离(字典)
定义一个L对象,线程隔离对象
t1 L.a t2 L.a 互不影响
Local对象 线程id号作为键
4. 变量修改
class A:
b = 1
my_obj = A()
def worker():
# 新线程修改b的值
my_obj.b = 2
t = threading.Thread(target=worker, name='wang')
t.start()
time.sleep(1)
print(my_obj.b) # 2
# 实例化三个对象 以隔离
request1 = Request()
request2 = Request()
request3 = Request()
5. 线程的隔离对现象Local:新线程的修改不影响主线程的值
from werkzeug.local import Local
class A:
b = 1
my_obj = Local()
my_obj.b = 1
def worker():
# 新线程修改b的值
my_obj.b = 2 # 新线程的需改不影响主线程,线程的隔离
print('in new thread b is : ' + str(my_obj.b)) # 2
t = threading.Thread(target=worker, name='wang')
t.start()
time.sleep(1)
# 主线程
print('in main thread b is : ' + str(my_obj.b)) # 1
两种栈:_request_ctx_stack _app_ctx_stack
管理上下文,线程隔离的栈 LocalStack()
_request_ctx_stack = LocalStack()
_app_ctx_stack = LocalStack()
LocalStack Local 字典 关系:
Local用字典的方式实现隔离
LocalStack封装了Local对象,作为一个属性,形成一个线程隔离的栈结构
如果一次封装解决不了问题,那么就再来一次~
7. LocalStack的push pop top
from werkzeug.local import LocalStack
# 栈Stcak的特性
s = LocalSrack()
s.push(1)
print(s.top()) # 1
print(s.top) # 1
print(s.pop()) # 1
print(s.top) # None
# 栈 后进先出
s.push(1)
s.push(2)
print(s.top) # 2
print(s.top) # 2
print(s.pop()) # 2
print(s.top) # 1
线程隔离(对象:requet请求上下文,app应用上下文)
from werkzeug.local import LocalStack
import time
import threading
# Local的特性
# 两个栈互不影响,线程隔离
my_stack = LocalStack()
my_stack.push(1)
print('栈顶元素为:', my_stack.top) # 1
def worker():
# 新线程
print('is a new thread', my_stack.top) # None
my_stack.push(2)
print('is after value: ', my_stack.top) # 2
new_t = threading.Thread(target=worker, name='wang')
new_t.start()
time.sleep(1)
# 主线程
print('主线程栈顶数据为:', my_stack.top) # 1
8. 使用线程隔离的意义在于:
使当前线程能够正确引用到他自己所创建的对象,而不是引用到其它线程创建的对象
对象是保存状态的地方
9. flask中线程隔离的有:
request session g
10. flask梳理