转: https://www.cnblogs.com/wangmingtao/p/9372611.html
22、上下文与出入栈
  22.1 请求过程
    请求过来,flask会实例化一个Request Context,就是请求上下文(这个请求上下文封装了请求的相关信息)生成请求上下文之后,将请求上下文推入栈中(栈:后进先出;队列:先进先出,flask中用LocalStack来表示栈,LocalStack是一个类,需要实例化,成_request_ctx_stack和_app_ctx_stack)
请求过来,通过push入栈
  22.2 入栈顺序
    request入栈的时候,会先检查app的栈,如果栈顶为空,会先将AppContext推入栈中,然后才会推入RequestContext,所以test.py中需要手动推入栈,而request请求不需要手动推,直接用就可以
    current_app和request都是栈顶元素,在操作这俩对象时,其实就是操作栈顶元素,这俩栈顶元素都是上下文,如果直接引入到外文件,元素是空的
离线应用、单元测试
# -*- coding=utf-8 -*-

from flask import Flask, current_app

app = Flask(__name__)

ctx = app.app_context()
ctx.push()
a = current_app
d = current_app.config['DEBUG']
ctx.pop()

test.py

23、flask上下文与with语句
# -*- coding=utf-8 -*-

from flask import Flask, current_app

app = Flask(__name__)

class MyResource:
def __enter__(self):
print('connect to resoure')
return self def __exit__(self, exc_type, exc_val, exc_tb):
print('close resource connection') def query(self):
print('query data') with MyResource as resource:
resource.query()

test.py

  23.1 实现了上下文协议的对象使用with
  23.2 对于实现了上下文协议的对象,通常称为上下文管理器
  23.3 一个上下文管理器如何实现上下文协议?只要一个对象实现了__enter__和__exit__就可以
  23.4 一个上下文表达式必须返回一个上下文管理器
  23.5 with语句,对资源的管理
 
24、阅读源码
  control+alt+左键/右键,返回或者进入函数内部
# -*- coding=utf-8 -*-

from flask import Flask
from app.models.book import db
from app.web.book import web def create_app():
app = Flask(__name__)
app.config.from_object('app.secure')
app.config.from_object('app.setting')
register_blueprint(app) db.init_app(app)
with app.app_context():
db.create_all()
# db.create_all(app=app)
return app def register_blueprint(app):
app.register_blueprint(web)
db create_all

fisher/app/__init__.py

25、进程(竞争计算机资源的基本单位)
  25.1 操作系统用来调度、分配资源的单位,每个应用程序至少有一个进程
  25.2 单核CPU 永远只能够执行一个应用程序?no,CPU可以在不同的应用程序进程之间切换
  25.3 进程/线程,切换时开销是非常大的,因为上下文是需要保存和加载消耗大
 
26、线程(是进程的一部分,可以只有一个进程 多个进程)
  26.1 线程之间切换所消耗的资源更小
    线程非常轻量,本身不负责管理资源也不用有资源,所以线程是去使用进程的相关资源的,所以让线程切换起来更加快速
  26.2 进程 分配资源
  26.3 线程 利用CPU执行代码
    eg:代码 指令 CPU来执行 资源,线程没有资源,有指令
  26.4 线程 自己不拥有资源,但是可以访问进程的资源
 
27、多线程
  27.1 主线程启用新的线程
# -*- coding=utf-8 -*-

import threading

def worker():
print('i am thread')
t = threading.current_thread()
print(t.getName()) t = threading.current_thread()
print(t.getName()) new_t = threading.Thread(target=worker, name='qiyue_thread')
new_t.start()

test/thread.py

  27.2 新的线程和主线程没有区别了,不会等线程执行完再执行下一个线程
# -*- coding=utf-8 -*-

import time
import threading def worker():
print('i am thread')
t = threading.current_thread()
time.sleep(100)
print(t.getName()) new_t = threading.Thread(target=worker, name='qiyue_thread')
new_t.start() t = threading.current_thread()
print(t.getName())

test/thread.py

    中间部分改为worker(),则会等worker执行结束再执行下面的,不是通过线程的方式调用,而是直接在主线程中调用的

  27.3 多线程编程好处
    (1)更加充分地利用CPU的性能优势,从而加快代码的执行速度
    (2)异步编程
    (3)单核CPU,同一时间只允许一个线程来使用CPU执行代码
    (4)多核CPU,完全有能力让不同的核去处理不同的线程,并行执行程序
    (5)python不能充分利用多核CPU的优势
 
28、全局解释器锁GIL(global interpreter lock)
  28.1 因为有GIL的存在,让python代码不管CPU有多少个核,开了多少个线程,同一时间只能在同一个核上面执行一个线程
  28.2 锁:线程安全
    多个线程共享一个进程的资源,可能多个线程同时访问一个资源,造成 线程不安全一般,为了保证线程安全,采用锁的机制。一旦对某个资源进行了加锁操作,只有拿到锁的线程才能对资源进行操作,执行完被释放之后才能被别的线程使用
  28.3 锁
    (1)细粒度锁 程序员 主动加锁
    (2)粗粒度锁 解释器 GIL
    (3)虽然多核CPU可以跑多个线程,但是python是需要解释器来解释的,由于GIL的存在,在python解释器上面,同一时刻只允许一个线程来执行
    (4)总结:CPU硬件是没有限制的,但是由于解释器,GIL只允许一个线程同时执行,一定程度上保证线程安全。可以采用多进程,可是多进程之间是不能互相访问的,如果想在进程之间共享资源,需要用到进程通信技术,相当麻烦,切换成本高
  28.4 对于IO密集型程序,多线程有意义
    (1)CPU密集型程序:非常严重的依赖CPU计算(圆周率计算、视频解码)
    (2)IO密集型程序:查询数据库、请求网络资源、读写文件
按照时间段消耗在那种操作上面来划分的
    (3)IO密集型主要花费在等待上面,不如让别的线程来使用CPU
 
29、开启flask多线程
  29.1 通过webserver开启多线程
    app.run(host='0.0.0.0', debug=app.config['DEBUG'], port=5000, threaded=True)
    单进程多线程
  29.2 对象是保存状态的地方。实例化三个不同的request对象分别用来保存三个请求的状态
  29.3 字典,用不同线程id号来线程隔离
    多线程,每个线程都有唯一标识,唯一标识为key,每个线程所实例化的Request对象作为value值
    一个request对象,一个request对象指向了一个字典的数据结构,字典包含了不同线程所创建的不同的Request实例化对象
  29.4 线程隔离对象
    (1)flask内部引用了werkzeug库,库内部有local模块,local模块有Local对象,线程隔离由Local对象完成,通过字典的方式
    (2)Local
# -*- coding=utf-8 -*-

import time
import threading from werkzeug.local import Local my_obj = Local()
my_obj.b = 1 def worker():
my_obj.b = 2
print('in new thread b is:' + str(my_obj.b)) new_t = threading.Thread(target=worker, name='qiyue_thread')
new_t.start()
time.sleep(1) # 主线程
print('in main thread b is:' + str(my_obj.b))

test/local.py

  29.5 线程隔离的栈

      (1)两个上下文,一个请求上下文,一个应用上下文,会在请求进来的时候被推进到栈中,_app_ctx_stack和_request_ctx_stack这两个变量名所指向的对象都是LocalStack()这样的类型,就是可以用来做线程隔离的栈
      (2)LocalStack Local 字典
        Local使用字典的方式实现的线程隔离
        LocalStack封装了线程对象,把Local对象作为它自己的一个属性,从而实现的一个线程隔离的栈结构
      (3)LocalStack基本用法
# -*- coding=utf-8 -*-

from werkzeug.local import LocalStack

s = LocalStack()
s.push(1) # 将一个元素推入到栈顶
print(s.top) # 将栈顶的元素取出来,只是取,不会删除
print(s.top) # top上方加了@property,作为属性,不需要括号
print(s.pop()) # pop是方法
print(s.top) s.push(1)
s.push(2)
print(s.top)
print(s.top)
print(s.pop())
print(s.top)

test/LocalStack.py

 

flask 高级编程 上下文与栈(转)的更多相关文章

  1. Python Flask高级编程

    第1章 课程导语介绍课程的内容1-1 开宗明义 试看1-2 课程维护与提问 第2章 Flask的基本原理与核心知识本章我们首先介绍Python官方推荐的最佳包与虚拟环境管理工具:Pipenv.接着我们 ...

  2. flask高级编程 LocalStack 线程隔离

    转:https://www.cnblogs.com/wangmingtao/p/9372611.html   30.LocalStack作为线程隔离对象的意义 30.1 数据结构 限制了某些能力 30 ...

  3. 学习python-20191208(1)-Python Flask高级编程开发鱼书_第03章_数据与flask路由

    视频01: 略...... ———————————————————————————————————————————————————————————— 视频02: 搜索需要外部数据源,也就是需要外部的A ...

  4. 学习python-20191230(1)-Python Flask高级编程开发鱼书_第04章_应用、蓝图与视图函数

    视频06: 1.自动导包快捷键——默认为alt + enter 键组合          选中的字符由小写变为大写——Ctrl + Shift + U键组合 2.DataRequired()——防止用 ...

  5. 学习python-20191217(1)-Python Flask高级编程开发鱼书_第04章_应用、蓝图与视图函数

    视频01: flask框架:最上层是app,它就像一个插线板一样,比如可以插入蓝图,还可以插入其他各种flask插件. 每个蓝图又可以插入很多视图函数,并可指定静态文件夹和模板文件夹. 好的代码结构, ...

  6. 学习python-20191208(2)-Python Flask高级编程开发鱼书_第03章_数据与flask路由

    视频06: 定义静态方法的两种方式: 1.在方法上方加上装饰@staticmethod 2.在方法上方加上装饰@classmethod  方法中要加参数cls  如:def search_by_isb ...

  7. 学习python-20191203-Python Flask高级编程开发鱼书_第02章 Flask的基本原理与核心知识

    视频01: 做一个产品时,一定要对自己的产品有一个明确的定位.并可以用一句话来概括自己产品的核心价值或功能. 鱼书网站几个功能 1.选择要赠送的书籍,向他人赠送书籍(价值功能,核心价值的主线): 2. ...

  8. python 全栈开发,Day139(websocket原理,flask之请求上下文)

    昨日内容回顾 flask和django对比 flask和django本质是一样的,都是web框架. 但是django自带了一些组件,flask虽然自带的组件比较少,但是它有很多的第三方插件. 那么在什 ...

  9. JavaScript高级编程——引用类型、Array数组使用、栈方法

    JavaScript高级编程——引用类型.Array数组使用.栈方法 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999 ...

随机推荐

  1. Emgu-WPF 激光雷达研究-移动物体检测

    原文:Emgu-WPF 激光雷达研究-移动物体检测 接上篇: https://blog.csdn.net/u013224722/article/details/80738619 先pose出效果图,下 ...

  2. Servlet的基础知识

    没有什么固定的结构, 就是稍微总结一下学习到的, 基本上想到哪里写到哪里. 关于基本的最HttpServlet 实际上Servlet是J2EE(也就是现在的Java EE)中规范的一个接口, 用于根据 ...

  3. js 操作样式

    <!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  4. MVC EF两种查询方法

    @*@model IQueryable<EFExam.Models.Product>*@@model IQueryable<EFExam.Models.ProductViewMode ...

  5. .NET 图片像素比较

    /// <summary> /// 图像比较.用于找出两副图片之间的差异位置 /// </summary> public class ImageComparer { /// & ...

  6. 展讯通信:文章"紫光收购后展讯困难重重”失实(展讯的成就确实很高)

    6月22日上午消息,展讯通信官方微信对自媒体文章<五大危机缠身,紫光收购后展讯困难重重>作出声明,称,其中内容严重失实,对公司造成了不良影响,并表示,将坚决采取法律手段维护自身的合法权益. ...

  7. Win8 Metro(C#)数字图像处理--2.44图像油画效果算法

    原文:Win8 Metro(C#)数字图像处理--2.44图像油画效果算法  [函数名称]   图像油画效果      OilpaintingProcess(WriteableBitmap src ...

  8. Android疑难杂症之Theme

    背景:最近在把自己之前写的一个应用换成Material Design风格,在看官方Guide后动手试了一试,没想到出门就遇到了坑,在换成Material Design风格的主题后,我设置了一下colo ...

  9. Android CTS Test failed to run to conmpletion 测试超时问题

    引用“Android cts all pass 全攻略”里面的一段话: ❀ testcase timeout 测试某个testcase的时候一直出现 “........”,迟迟没有pass或者fail ...

  10. linux程序机制入门

    GCC环境 类debian系统运行 apt-get install build-essential 安装gcc环境. 编写c语言程序后,运行 gcc ./hello.c 会得到一个名为 a.out 的 ...