zoukankan      html  css  js  c++  java
  • Flask--偏函数, 线程安全, 请求上下文

    一 . 偏函数

    from functools import partial
    
    def func(a, b):
        return a + b
    
    new_func = partial(func, 3, 4)  # 3,4就是a,b, 也可传*args  **kwargs
    ret = new_func()
    
    # 也可以这样写,结果是一样的
    # new_func = partial(func, 3)  # 这个3是a
    # ret = new_func(4)  # 这个4是b
    print(ret)  # 7

    二 . 线程安全

    # 当使用公共变量的时候,开启多线程,数据是不安全的, 可能会被修改,
        如果数据是安全的,那么下面代码打印的应该0-9不重复且无序
    import time
    import threading
    from threading import Thread
    
    class Foo(object):
        pass
    
    foo = Foo()
    
    def func(i):
        foo.num = i
        time.sleep(1)
        print(foo.num, threading.current_thread().ident, foo)
    for i in range(10):
        task = Thread(target=func, args=(i,))
        task.start()

      

      解决办法

    # 我们既想使用多线程,又想让数据安全,也就是不共享,这里需要用到 local
    import time
    from threading import Thread, local
    import threading
    
    class Foo(local):
        pass
    
    foo = Foo()
    
    def func(i):
        foo.num = i
        time.sleep(1)
        print(foo.num, threading.current_thread().ident, foo)
    
    for i in range(10):
        task = Thread(target=func, args=(i,))
        task.start()

      

    这里local帮助我们节省了时间,却消耗了空间, 但是这点空间相对于线程执行效率来说不知一提

    三 . 请求上下文

      既然谈到了请求上下文,那么我们需要知道一下什么是上下文,说白了就是请求从发起到完成所需要的环境

      

    Flask中的request不同于Django,它是导入进来的,这个是,也就是说它是全局变量, 为了避免多线程来应用它而导致它产生改变,flask采用了local这个特殊的对象,
      这个local对象可以对线程进行隔离,也就是说有了这个local,每个线程对local对象进行修改都不影响其他线程,在请求后,LocalStack栈中会销毁请求上下文对象.
    实现这种原理就是用线程的ID作为key来保存,每个线程都会找到自己的ID.
    但是flask用的不是threading.local,而不是werkzeuk的local,因为:
      1.werkzeuk自定义的__storage__保存不同线程的状态
      2.werkzeuk通过get_ident函数来获取线程标识符(区分用的ID)
      3.python3.5以上开始对协程支持,如果用threading.local,可能造成变量在接收时相互干扰,因为一个线程中有多个协程去请求
      4.除了local外,werkzeuk还实现了两种数据结构,LocalStack,LocalProxy

      现在来看一下请求上下文的过程

    服务器框架在接收http请求的时候,去调用app, app在执行run方法的时候,下面执行了werkzeuk模块中的run_simple,
    werkzeuk触发了flask的__call__方法,__call__方法返回的是wsgi_app,直接执行wsgi_app.
    # 详细过程见链接: https://www.processon.com/view/link/5cb1d4c6e4b069ac5a259818
  • 相关阅读:
    Pycharm(Mac版)快捷键操作篇
    Ubuntu报E: 仓库 “http://ppa.launchpad.net/webupd8team/sublime-text-3/ubuntu bionic Release” 没有 Release 文件。
    Ubuntu安装出现无法锁定管理目录是否有其他进程正在占用它?
    解决Ubuntu(18.04LTS)和win10电脑之间无法复制粘贴问题
    数据库的基本查询
    Ubuntu下数据库的操作
    Ubuntu中vi上下左右键退格键失灵的问题
    Ubuntu 18.04TLS命令安装Pycharm并固定在快速启动栏
    Ubuntu下mysql连接Navicat premium报错
    Ubuntu安装mysql报ERROR 1698 (28000): Access denied for user 'root'@'localhost',有效的解决办法
  • 原文地址:https://www.cnblogs.com/attila/p/10698958.html
Copyright © 2011-2022 走看看