• flask框架(十二):上下文管理***


    情况一:单进程单线程

      基于全局变量实现。

    情况二:单进程多线程

      基于threading.local对象。

      threading.local对象,用于为每个线程开辟一块空间来保存它独有的值。

    # -*- coding: utf-8 -*-
    # @Author : Felix Wang
    # @time   : 2018/7/5 15:43
    
    import threading
    
    # 使用threading.local()时取到的是想要的值,数据操作是安全的
    local_values = threading.local()
    
    
    # 没有使用threading.local()时,取到的不是自己想要的值
    # class Foo(object):
    #     def __init__(self):
    #         self.name=0
    # local_values=Foo()
    
    def func(num):
        local_values.name = num
        import time
        time.sleep(1)
        print(local_values.name, threading.current_thread().name)
    
    
    for i in range(20):
        th = threading.Thread(target=func, args=(i,), name='线程{}'.format(str(i)))
        th.start()
    单进程多线程情况

    情况三:单进程单线程(多个协程),threading.local对象做不到。通过自定义类似threading.local对象

    # -*- coding: utf-8 -*-
    # @Author : Felix Wang
    # @time   : 2018/7/5 16:06
    import threading
    
    try:
        from greenlet import getcurrent as get_ident  # 支持协程
    except ImportError:
        try:
            from thread import get_ident
        except ImportError:
            from _thread import get_ident  # 获取线程的唯一标识
    
    
    # 实现方式一
    class Local(object):
        def __init__(self):
            self.storage = {}
            self.get_ident = get_ident
    
        def set(self, k, v):
            ident = self.get_ident()
            origin = self.storage.get(ident)
            if not origin:
                origin = {k: v}
            else:
                origin[k] = v
            self.storage[ident] = origin
    
        def get(self, k):
            ident = self.get_ident()
            origin = self.storage.get(ident)
            if not origin:
                return None
            return origin.get(k, None)
    
    
    local_values = Local()
    
    
    def task(num):
        local_values.set('name', num)
        import time
        time.sleep(1)
        print(local_values.get('name'), threading.current_thread().name)
    
    
    for i in range(20):
        th = threading.Thread(target=task, args=(i,))
        th.start()
    
    
    # 实现方式二
    class Local2(object):
        def __init__(self):
            object.__setattr__(self, '__storage__', {})
            object.__setattr__(self, '__ident_func__', get_ident)
            # self.storage = {}
            # self.get_ident = get_ident
    
        def __getattr__(self, name):
            try:
                return self.__storage__[self.__ident_func__()][name]
            except KeyError:
                raise AttributeError(name)
    
        def __setattr__(self, key, value):
            ident = self.__ident_func__()
            storage = self.__storage__
            try:
                storage[ident][key] = value
            except KeyError:
                storage[ident] = {key: value}
    
    
    local_values2 = Local2()
    
    
    def task(num):
        local_values2.name = num
        import time
        time.sleep(1)
        print(local_values2.name, threading.current_thread().name)
    
    
    for i in range(20, 40):
        th = threading.Thread(target=task, args=(i,))
        th.start()
    自定义local对象
  • 相关阅读:
    java开发中的重中之重-------mysql(基础篇)
    开发中的重点-----设计模式
    java 不可不知的数据库知识-----事物
    redis 入门笔记
    转 Java对日期Date类进行加减运算一二三
    Ajax 中的高级请求和响应
    Ajax之基础总结
    Spring中的国际化资源以及视图跳转
    javascript基础总结
    SpringMVC的表单标签
  • 原文地址:https://www.cnblogs.com/felixwang2/p/9269330.html
Copyright © 2020-2023  润新知