1.threading
查看当前线程
开启新的线程
import threading def worker(): print('new thread..') print(threading.current_thread().getName()) if __name__ == '__main__': print('hello') t = threading.current_thread() print(t.getName()) # MainThread th1 = threading.Thread(target=worker, name='my Thread') th1.start()
2.锁
细粒度锁:主动加的锁
粗粒度锁:解释器加的锁 GIL
3.webserver
flask内置的web服务器是单进程、单线程的,不能同时处理多个请求,flask内置的web服务器可以用来调试,测试。
可以对flask自带的服务器开启多线程模式:
app.run(threaded=Ture) 【单进程、多线程】
多线程带来的问题:一个request变量指向多个Request实例。
解决办法:使用字典,线程隔离,request = { thread1_id:request1,.... } key为线程的唯一标识
from werkzeug.local import Local class A(object): a = 100 obj = Local() obj.a = 1 def fun(): obj.a = 20 print('in new thread obj.a ia', obj.a) if __name__ == '__main__': t = threading.Thread(target=fun, name='mythread') t.start() time.sleep(1) print('in main thread obj.a is' ,obj.a)
Local模块的原理就是用线程的id作为字典的key 【werkzeug模块】
LocalStack使用Local的线程隔离栈,每个线程有独立的栈
LocalStack -->AppContext -->FlaskApp
LocalStack栈push AppContext、RequestContext
current_app为栈顶元素的app属性
request为栈顶元素的request属性